Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
mariadb
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
559e2f1c
Commit
559e2f1c
authored
Jul 24, 2009
by
Satya B
Browse files
Options
Browse Files
Download
Plain Diff
merge to mysql-5.0-bugteam
parents
34255325
1e32574c
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
105 additions
and
21 deletions
+105
-21
include/violite.h
include/violite.h
+9
-1
mysql-test/r/subselect.result
mysql-test/r/subselect.result
+22
-0
mysql-test/t/subselect.test
mysql-test/t/subselect.test
+22
-0
sql/item.cc
sql/item.cc
+1
-0
sql/item_subselect.cc
sql/item_subselect.cc
+4
-0
sql/mysqld.cc
sql/mysqld.cc
+5
-2
vio/viosslfactories.c
vio/viosslfactories.c
+42
-18
No files found.
include/violite.h
View file @
559e2f1c
...
@@ -109,6 +109,14 @@ typedef my_socket YASSL_SOCKET_T;
...
@@ -109,6 +109,14 @@ typedef my_socket YASSL_SOCKET_T;
#include <openssl/ssl.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/err.h>
enum
enum_ssl_init_error
{
SSL_INITERR_NOERROR
=
0
,
SSL_INITERR_CERT
,
SSL_INITERR_KEY
,
SSL_INITERR_NOMATCH
,
SSL_INITERR_BAD_PATHS
,
SSL_INITERR_CIPHERS
,
SSL_INITERR_MEMFAIL
,
SSL_INITERR_LASTERR
};
const
char
*
sslGetErrString
(
enum
enum_ssl_init_error
err
);
struct
st_VioSSLFd
struct
st_VioSSLFd
{
{
SSL_CTX
*
ssl_context
;
SSL_CTX
*
ssl_context
;
...
@@ -124,7 +132,7 @@ struct st_VioSSLFd
...
@@ -124,7 +132,7 @@ struct st_VioSSLFd
struct
st_VioSSLFd
struct
st_VioSSLFd
*
new_VioSSLAcceptorFd
(
const
char
*
key_file
,
const
char
*
cert_file
,
*
new_VioSSLAcceptorFd
(
const
char
*
key_file
,
const
char
*
cert_file
,
const
char
*
ca_file
,
const
char
*
ca_path
,
const
char
*
ca_file
,
const
char
*
ca_path
,
const
char
*
cipher
);
const
char
*
cipher
,
enum
enum_ssl_init_error
*
error
);
#endif
/* HAVE_OPENSSL */
#endif
/* HAVE_OPENSSL */
#ifdef HAVE_SMEM
#ifdef HAVE_SMEM
...
...
mysql-test/r/subselect.result
View file @
559e2f1c
...
@@ -4452,4 +4452,26 @@ WHERE 1 IN (SELECT id FROM t1) WITH CHECK OPTION;
...
@@ -4452,4 +4452,26 @@ WHERE 1 IN (SELECT id FROM t1) WITH CHECK OPTION;
DELETE FROM v3;
DELETE FROM v3;
DROP VIEW v1,v2,v3;
DROP VIEW v1,v2,v3;
DROP TABLE t1,t2;
DROP TABLE t1,t2;
#
# Bug#45061: Incorrectly market field caused wrong result.
#
CREATE TABLE `C` (
`int_nokey` int(11) NOT NULL,
`int_key` int(11) NOT NULL,
KEY `int_key` (`int_key`)
);
INSERT INTO `C` VALUES (9,9), (0,0), (8,6), (3,6), (7,6), (0,4),
(1,7), (9,4), (0,8), (9,4), (0,7), (5,5), (0,0), (8,5), (8,7),
(5,2), (1,8), (7,0), (0,9), (9,5);
SELECT * FROM C WHERE `int_key` IN (SELECT `int_nokey`);
int_nokey int_key
9 9
0 0
5 5
0 0
EXPLAIN EXTENDED SELECT * FROM C WHERE `int_key` IN (SELECT `int_nokey`);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY C ALL NULL NULL NULL NULL 20 Using where
DROP TABLE C;
# End of test for bug#45061.
End of 5.0 tests.
End of 5.0 tests.
mysql-test/t/subselect.test
View file @
559e2f1c
...
@@ -3428,4 +3428,26 @@ DELETE FROM v3;
...
@@ -3428,4 +3428,26 @@ DELETE FROM v3;
DROP
VIEW
v1
,
v2
,
v3
;
DROP
VIEW
v1
,
v2
,
v3
;
DROP
TABLE
t1
,
t2
;
DROP
TABLE
t1
,
t2
;
--
echo
#
--
echo
# Bug#45061: Incorrectly market field caused wrong result.
--
echo
#
CREATE
TABLE
`C`
(
`int_nokey`
int
(
11
)
NOT
NULL
,
`int_key`
int
(
11
)
NOT
NULL
,
KEY
`int_key`
(
`int_key`
)
);
INSERT
INTO
`C`
VALUES
(
9
,
9
),
(
0
,
0
),
(
8
,
6
),
(
3
,
6
),
(
7
,
6
),
(
0
,
4
),
(
1
,
7
),
(
9
,
4
),
(
0
,
8
),
(
9
,
4
),
(
0
,
7
),
(
5
,
5
),
(
0
,
0
),
(
8
,
5
),
(
8
,
7
),
(
5
,
2
),
(
1
,
8
),
(
7
,
0
),
(
0
,
9
),
(
9
,
5
);
--
disable_warnings
SELECT
*
FROM
C
WHERE
`int_key`
IN
(
SELECT
`int_nokey`
);
EXPLAIN
EXTENDED
SELECT
*
FROM
C
WHERE
`int_key`
IN
(
SELECT
`int_nokey`
);
--
enable_warnings
DROP
TABLE
C
;
--
echo
# End of test for bug#45061.
--
echo
End
of
5.0
tests
.
--
echo
End
of
5.0
tests
.
sql/item.cc
View file @
559e2f1c
...
@@ -598,6 +598,7 @@ bool Item_ident::remove_dependence_processor(byte * arg)
...
@@ -598,6 +598,7 @@ bool Item_ident::remove_dependence_processor(byte * arg)
DBUG_ENTER
(
"Item_ident::remove_dependence_processor"
);
DBUG_ENTER
(
"Item_ident::remove_dependence_processor"
);
if
(
depended_from
==
(
st_select_lex
*
)
arg
)
if
(
depended_from
==
(
st_select_lex
*
)
arg
)
depended_from
=
0
;
depended_from
=
0
;
context
=
&
((
st_select_lex
*
)
arg
)
->
context
;
DBUG_RETURN
(
0
);
DBUG_RETURN
(
0
);
}
}
...
...
sql/item_subselect.cc
View file @
559e2f1c
...
@@ -1145,6 +1145,10 @@ Item_in_subselect::single_value_transformer(JOIN *join,
...
@@ -1145,6 +1145,10 @@ Item_in_subselect::single_value_transformer(JOIN *join,
else
else
{
{
// it is single select without tables => possible optimization
// it is single select without tables => possible optimization
// remove the dependence mark since the item is moved to upper
// select and is not outer anymore.
item
->
walk
(
&
Item
::
remove_dependence_processor
,
(
byte
*
)
select_lex
->
outer_select
());
item
=
func
->
create
(
left_expr
,
item
);
item
=
func
->
create
(
left_expr
,
item
);
// fix_field of item will be done in time of substituting
// fix_field of item will be done in time of substituting
substitution
=
item
;
substitution
=
item
;
...
...
sql/mysqld.cc
View file @
559e2f1c
...
@@ -3249,14 +3249,17 @@ static void init_ssl()
...
@@ -3249,14 +3249,17 @@ static void init_ssl()
#ifdef HAVE_OPENSSL
#ifdef HAVE_OPENSSL
if
(
opt_use_ssl
)
if
(
opt_use_ssl
)
{
{
enum
enum_ssl_init_error
error
=
SSL_INITERR_NOERROR
;
/* having ssl_acceptor_fd != 0 signals the use of SSL */
/* having ssl_acceptor_fd != 0 signals the use of SSL */
ssl_acceptor_fd
=
new_VioSSLAcceptorFd
(
opt_ssl_key
,
opt_ssl_cert
,
ssl_acceptor_fd
=
new_VioSSLAcceptorFd
(
opt_ssl_key
,
opt_ssl_cert
,
opt_ssl_ca
,
opt_ssl_capath
,
opt_ssl_ca
,
opt_ssl_capath
,
opt_ssl_cipher
);
opt_ssl_cipher
,
&
error
);
DBUG_PRINT
(
"info"
,(
"ssl_acceptor_fd: 0x%lx"
,
(
long
)
ssl_acceptor_fd
));
DBUG_PRINT
(
"info"
,(
"ssl_acceptor_fd: 0x%lx"
,
(
long
)
ssl_acceptor_fd
));
if
(
!
ssl_acceptor_fd
)
if
(
!
ssl_acceptor_fd
)
{
{
sql_print_warning
(
"Failed to setup SSL"
);
sql_print_warning
(
"Failed to setup SSL"
);
sql_print_warning
(
"SSL error: %s"
,
sslGetErrString
(
error
));
opt_use_ssl
=
0
;
opt_use_ssl
=
0
;
have_ssl
=
SHOW_OPTION_DISABLED
;
have_ssl
=
SHOW_OPTION_DISABLED
;
}
}
...
@@ -3747,7 +3750,6 @@ int main(int argc, char **argv)
...
@@ -3747,7 +3750,6 @@ int main(int argc, char **argv)
select_thread
=
pthread_self
();
select_thread
=
pthread_self
();
select_thread_in_use
=
1
;
select_thread_in_use
=
1
;
init_ssl
();
#ifdef HAVE_LIBWRAP
#ifdef HAVE_LIBWRAP
libwrapName
=
my_progname
+
dirname_length
(
my_progname
);
libwrapName
=
my_progname
+
dirname_length
(
my_progname
);
...
@@ -3804,6 +3806,7 @@ we force server id to 2, but this MySQL server will not act as a slave.");
...
@@ -3804,6 +3806,7 @@ we force server id to 2, but this MySQL server will not act as a slave.");
if
(
init_server_components
())
if
(
init_server_components
())
exit
(
1
);
exit
(
1
);
init_ssl
();
network_init
();
network_init
();
#ifdef __WIN__
#ifdef __WIN__
...
...
vio/viosslfactories.c
View file @
559e2f1c
...
@@ -73,9 +73,28 @@ report_errors()
...
@@ -73,9 +73,28 @@ report_errors()
DBUG_VOID_RETURN
;
DBUG_VOID_RETURN
;
}
}
static
const
char
*
ssl_error_string
[]
=
{
"No error"
,
"Unable to get certificate"
,
"Unable to get private key"
,
"Private key does not match the certificate public key"
"SSL_CTX_set_default_verify_paths failed"
,
"Failed to set ciphers to use"
,
"SSL_CTX_new failed"
};
const
char
*
sslGetErrString
(
enum
enum_ssl_init_error
e
)
{
DBUG_ASSERT
(
SSL_INITERR_NOERROR
<
e
&&
e
<
SSL_INITERR_LASTERR
);
return
ssl_error_string
[
e
];
}
static
int
static
int
vio_set_cert_stuff
(
SSL_CTX
*
ctx
,
const
char
*
cert_file
,
const
char
*
key_file
)
vio_set_cert_stuff
(
SSL_CTX
*
ctx
,
const
char
*
cert_file
,
const
char
*
key_file
,
enum
enum_ssl_init_error
*
error
)
{
{
DBUG_ENTER
(
"vio_set_cert_stuff"
);
DBUG_ENTER
(
"vio_set_cert_stuff"
);
DBUG_PRINT
(
"enter"
,
(
"ctx: 0x%lx cert_file: %s key_file: %s"
,
DBUG_PRINT
(
"enter"
,
(
"ctx: 0x%lx cert_file: %s key_file: %s"
,
...
@@ -84,9 +103,10 @@ vio_set_cert_stuff(SSL_CTX *ctx, const char *cert_file, const char *key_file)
...
@@ -84,9 +103,10 @@ vio_set_cert_stuff(SSL_CTX *ctx, const char *cert_file, const char *key_file)
{
{
if
(
SSL_CTX_use_certificate_file
(
ctx
,
cert_file
,
SSL_FILETYPE_PEM
)
<=
0
)
if
(
SSL_CTX_use_certificate_file
(
ctx
,
cert_file
,
SSL_FILETYPE_PEM
)
<=
0
)
{
{
DBUG_PRINT
(
"error"
,(
"unable to get certificate from '%s'"
,
cert_file
));
*
error
=
SSL_INITERR_CERT
;
DBUG_PRINT
(
"error"
,(
"%s from file '%s'"
,
sslGetErrString
(
*
error
),
cert_file
));
DBUG_EXECUTE
(
"error"
,
ERR_print_errors_fp
(
DBUG_FILE
););
DBUG_EXECUTE
(
"error"
,
ERR_print_errors_fp
(
DBUG_FILE
););
fprintf
(
stderr
,
"SSL error:
Unable to get certificate from '%s'
\n
"
,
fprintf
(
stderr
,
"SSL error:
%s from '%s'
\n
"
,
sslGetErrString
(
*
error
)
,
cert_file
);
cert_file
);
fflush
(
stderr
);
fflush
(
stderr
);
DBUG_RETURN
(
1
);
DBUG_RETURN
(
1
);
...
@@ -97,9 +117,10 @@ vio_set_cert_stuff(SSL_CTX *ctx, const char *cert_file, const char *key_file)
...
@@ -97,9 +117,10 @@ vio_set_cert_stuff(SSL_CTX *ctx, const char *cert_file, const char *key_file)
if
(
SSL_CTX_use_PrivateKey_file
(
ctx
,
key_file
,
SSL_FILETYPE_PEM
)
<=
0
)
if
(
SSL_CTX_use_PrivateKey_file
(
ctx
,
key_file
,
SSL_FILETYPE_PEM
)
<=
0
)
{
{
DBUG_PRINT
(
"error"
,
(
"unable to get private key from '%s'"
,
key_file
));
*
error
=
SSL_INITERR_KEY
;
DBUG_PRINT
(
"error"
,
(
"%s from file '%s'"
,
sslGetErrString
(
*
error
),
key_file
));
DBUG_EXECUTE
(
"error"
,
ERR_print_errors_fp
(
DBUG_FILE
););
DBUG_EXECUTE
(
"error"
,
ERR_print_errors_fp
(
DBUG_FILE
););
fprintf
(
stderr
,
"SSL error:
Unable to get private key from '%s'
\n
"
,
fprintf
(
stderr
,
"SSL error:
%s from '%s'
\n
"
,
sslGetErrString
(
*
error
)
,
key_file
);
key_file
);
fflush
(
stderr
);
fflush
(
stderr
);
DBUG_RETURN
(
1
);
DBUG_RETURN
(
1
);
...
@@ -111,12 +132,10 @@ vio_set_cert_stuff(SSL_CTX *ctx, const char *cert_file, const char *key_file)
...
@@ -111,12 +132,10 @@ vio_set_cert_stuff(SSL_CTX *ctx, const char *cert_file, const char *key_file)
*/
*/
if
(
!
SSL_CTX_check_private_key
(
ctx
))
if
(
!
SSL_CTX_check_private_key
(
ctx
))
{
{
DBUG_PRINT
(
"error"
,
*
error
=
SSL_INITERR_NOMATCH
;
(
"Private key does not match the certificate public key"
));
DBUG_PRINT
(
"error"
,
(
"%s"
,
sslGetErrString
(
*
error
)
));
DBUG_EXECUTE
(
"error"
,
ERR_print_errors_fp
(
DBUG_FILE
););
DBUG_EXECUTE
(
"error"
,
ERR_print_errors_fp
(
DBUG_FILE
););
fprintf
(
stderr
,
fprintf
(
stderr
,
"SSL error: %s
\n
"
,
sslGetErrString
(
*
error
));
"SSL error: "
"Private key does not match the certificate public key
\n
"
);
fflush
(
stderr
);
fflush
(
stderr
);
DBUG_RETURN
(
1
);
DBUG_RETURN
(
1
);
}
}
...
@@ -229,7 +248,8 @@ static void check_ssl_init()
...
@@ -229,7 +248,8 @@ static void check_ssl_init()
static
struct
st_VioSSLFd
*
static
struct
st_VioSSLFd
*
new_VioSSLFd
(
const
char
*
key_file
,
const
char
*
cert_file
,
new_VioSSLFd
(
const
char
*
key_file
,
const
char
*
cert_file
,
const
char
*
ca_file
,
const
char
*
ca_path
,
const
char
*
ca_file
,
const
char
*
ca_path
,
const
char
*
cipher
,
SSL_METHOD
*
method
)
const
char
*
cipher
,
SSL_METHOD
*
method
,
enum
enum_ssl_init_error
*
error
)
{
{
DH
*
dh
;
DH
*
dh
;
struct
st_VioSSLFd
*
ssl_fd
;
struct
st_VioSSLFd
*
ssl_fd
;
...
@@ -243,7 +263,8 @@ new_VioSSLFd(const char *key_file, const char *cert_file,
...
@@ -243,7 +263,8 @@ new_VioSSLFd(const char *key_file, const char *cert_file,
if
(
!
(
ssl_fd
->
ssl_context
=
SSL_CTX_new
(
method
)))
if
(
!
(
ssl_fd
->
ssl_context
=
SSL_CTX_new
(
method
)))
{
{
DBUG_PRINT
(
"error"
,
(
"SSL_CTX_new failed"
));
*
error
=
SSL_INITERR_MEMFAIL
;
DBUG_PRINT
(
"error"
,
(
"%s"
,
sslGetErrString
(
*
error
)));
report_errors
();
report_errors
();
my_free
((
void
*
)
ssl_fd
,
MYF
(
0
));
my_free
((
void
*
)
ssl_fd
,
MYF
(
0
));
DBUG_RETURN
(
0
);
DBUG_RETURN
(
0
);
...
@@ -257,7 +278,8 @@ new_VioSSLFd(const char *key_file, const char *cert_file,
...
@@ -257,7 +278,8 @@ new_VioSSLFd(const char *key_file, const char *cert_file,
if
(
cipher
&&
if
(
cipher
&&
SSL_CTX_set_cipher_list
(
ssl_fd
->
ssl_context
,
cipher
)
==
0
)
SSL_CTX_set_cipher_list
(
ssl_fd
->
ssl_context
,
cipher
)
==
0
)
{
{
DBUG_PRINT
(
"error"
,
(
"failed to set ciphers to use"
));
*
error
=
SSL_INITERR_CIPHERS
;
DBUG_PRINT
(
"error"
,
(
"%s"
,
sslGetErrString
(
*
error
)));
report_errors
();
report_errors
();
SSL_CTX_free
(
ssl_fd
->
ssl_context
);
SSL_CTX_free
(
ssl_fd
->
ssl_context
);
my_free
((
void
*
)
ssl_fd
,
MYF
(
0
));
my_free
((
void
*
)
ssl_fd
,
MYF
(
0
));
...
@@ -270,7 +292,8 @@ new_VioSSLFd(const char *key_file, const char *cert_file,
...
@@ -270,7 +292,8 @@ new_VioSSLFd(const char *key_file, const char *cert_file,
DBUG_PRINT
(
"warning"
,
(
"SSL_CTX_load_verify_locations failed"
));
DBUG_PRINT
(
"warning"
,
(
"SSL_CTX_load_verify_locations failed"
));
if
(
SSL_CTX_set_default_verify_paths
(
ssl_fd
->
ssl_context
)
==
0
)
if
(
SSL_CTX_set_default_verify_paths
(
ssl_fd
->
ssl_context
)
==
0
)
{
{
DBUG_PRINT
(
"error"
,
(
"SSL_CTX_set_default_verify_paths failed"
));
*
error
=
SSL_INITERR_BAD_PATHS
;
DBUG_PRINT
(
"error"
,
(
"%s"
,
sslGetErrString
(
*
error
)));
report_errors
();
report_errors
();
SSL_CTX_free
(
ssl_fd
->
ssl_context
);
SSL_CTX_free
(
ssl_fd
->
ssl_context
);
my_free
((
void
*
)
ssl_fd
,
MYF
(
0
));
my_free
((
void
*
)
ssl_fd
,
MYF
(
0
));
...
@@ -278,7 +301,7 @@ new_VioSSLFd(const char *key_file, const char *cert_file,
...
@@ -278,7 +301,7 @@ new_VioSSLFd(const char *key_file, const char *cert_file,
}
}
}
}
if
(
vio_set_cert_stuff
(
ssl_fd
->
ssl_context
,
cert_file
,
key_file
))
if
(
vio_set_cert_stuff
(
ssl_fd
->
ssl_context
,
cert_file
,
key_file
,
error
))
{
{
DBUG_PRINT
(
"error"
,
(
"vio_set_cert_stuff failed"
));
DBUG_PRINT
(
"error"
,
(
"vio_set_cert_stuff failed"
));
report_errors
();
report_errors
();
...
@@ -306,6 +329,7 @@ new_VioSSLConnectorFd(const char *key_file, const char *cert_file,
...
@@ -306,6 +329,7 @@ new_VioSSLConnectorFd(const char *key_file, const char *cert_file,
{
{
struct
st_VioSSLFd
*
ssl_fd
;
struct
st_VioSSLFd
*
ssl_fd
;
int
verify
=
SSL_VERIFY_PEER
;
int
verify
=
SSL_VERIFY_PEER
;
enum
enum_ssl_init_error
dummy
;
/*
/*
Turn off verification of servers certificate if both
Turn off verification of servers certificate if both
...
@@ -315,7 +339,7 @@ new_VioSSLConnectorFd(const char *key_file, const char *cert_file,
...
@@ -315,7 +339,7 @@ new_VioSSLConnectorFd(const char *key_file, const char *cert_file,
verify
=
SSL_VERIFY_NONE
;
verify
=
SSL_VERIFY_NONE
;
if
(
!
(
ssl_fd
=
new_VioSSLFd
(
key_file
,
cert_file
,
ca_file
,
if
(
!
(
ssl_fd
=
new_VioSSLFd
(
key_file
,
cert_file
,
ca_file
,
ca_path
,
cipher
,
TLSv1_client_method
())))
ca_path
,
cipher
,
TLSv1_client_method
()
,
&
dummy
)))
{
{
return
0
;
return
0
;
}
}
...
@@ -336,12 +360,12 @@ new_VioSSLConnectorFd(const char *key_file, const char *cert_file,
...
@@ -336,12 +360,12 @@ new_VioSSLConnectorFd(const char *key_file, const char *cert_file,
struct
st_VioSSLFd
*
struct
st_VioSSLFd
*
new_VioSSLAcceptorFd
(
const
char
*
key_file
,
const
char
*
cert_file
,
new_VioSSLAcceptorFd
(
const
char
*
key_file
,
const
char
*
cert_file
,
const
char
*
ca_file
,
const
char
*
ca_path
,
const
char
*
ca_file
,
const
char
*
ca_path
,
const
char
*
cipher
)
const
char
*
cipher
,
enum
enum_ssl_init_error
*
error
)
{
{
struct
st_VioSSLFd
*
ssl_fd
;
struct
st_VioSSLFd
*
ssl_fd
;
int
verify
=
SSL_VERIFY_PEER
|
SSL_VERIFY_CLIENT_ONCE
;
int
verify
=
SSL_VERIFY_PEER
|
SSL_VERIFY_CLIENT_ONCE
;
if
(
!
(
ssl_fd
=
new_VioSSLFd
(
key_file
,
cert_file
,
ca_file
,
if
(
!
(
ssl_fd
=
new_VioSSLFd
(
key_file
,
cert_file
,
ca_file
,
ca_path
,
cipher
,
TLSv1_server_method
())))
ca_path
,
cipher
,
TLSv1_server_method
()
,
error
)))
{
{
return
0
;
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