Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenHarmony
Third Party Openssl
提交
eb90a483
T
Third Party Openssl
项目概览
OpenHarmony
/
Third Party Openssl
8 个月 前同步成功
通知
8
Star
18
Fork
1
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
T
Third Party Openssl
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
eb90a483
编写于
2月 28, 1999
作者:
B
Ben Laurie
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add functions to add certs to stacks, used for CA file/path stuff in servers.
上级
49bc2624
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
161 addition
and
48 deletion
+161
-48
CHANGES
CHANGES
+8
-0
crypto/bio/bio.h
crypto/bio/bio.h
+3
-1
crypto/stack/stack.c
crypto/stack/stack.c
+5
-1
crypto/stack/stack.h
crypto/stack/stack.h
+2
-2
openssl.doxy
openssl.doxy
+1
-1
ssl/ssl.err
ssl/ssl.err
+5
-2
ssl/ssl.h
ssl/ssl.h
+9
-2
ssl/ssl_cert.c
ssl/ssl_cert.c
+123
-37
ssl/ssl_err.c
ssl/ssl_err.c
+5
-2
未找到文件。
CHANGES
浏览文件 @
eb90a483
...
...
@@ -5,6 +5,14 @@
Changes between 0.9.1c and 0.9.2
*) Add new certificate file to stack functions, SSL_add_cert_file_to_stack()
and SSL_add_cert_dir_to_stack(). These largely supplant
SSL_load_client_CA_file(), and can be used to add multiple certs easily to
a stack (usually this is then handed to SSL_CTX_set_client_CA_list()).
This means that Apache-SSL and similar packages don't have to mess around
to add as many CAs as they want to the preferred list.
[Ben Laurie]
*) Experiment with doxygen documentation. Currently only partially applied to
ssl/ssl_lib.c.
See http://www.stack.nl/~dimitri/doxygen/index.html, and run doxygen with
...
...
crypto/bio/bio.h
浏览文件 @
eb90a483
...
...
@@ -383,8 +383,10 @@ int BIO_get_ex_new_index(long argl, char *argp, int (*new_func)(),
#define BIO_seek(b,ofs) (int)BIO_ctrl(b,BIO_C_FILE_SEEK,ofs,NULL)
#define BIO_tell(b) (int)BIO_ctrl(b,BIO_C_FILE_TELL,0,NULL)
/* name is cast to lose const, but might be better to route through a function
so we can do it safely */
#define BIO_read_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \
BIO_CLOSE|BIO_FP_READ,name)
BIO_CLOSE|BIO_FP_READ,
(char *)
name)
#define BIO_write_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \
BIO_CLOSE|BIO_FP_WRITE,name)
#define BIO_append_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \
...
...
crypto/stack/stack.c
浏览文件 @
eb90a483
...
...
@@ -82,13 +82,17 @@ char *STACK_version="Stack part of OpenSSL 0.9.2 31-Dec-1998";
#include <errno.h>
void
sk_set_cmp_func
(
sk
,
c
)
int
(
*
sk_set_cmp_func
(
sk
,
c
))(
)
STACK
*
sk
;
int
(
*
c
)();
{
int
(
*
old
)()
=
sk
->
comp
;
if
(
sk
->
comp
!=
c
)
sk
->
sorted
=
0
;
sk
->
comp
=
c
;
return
old
;
}
STACK
*
sk_dup
(
sk
)
...
...
crypto/stack/stack.h
浏览文件 @
eb90a483
...
...
@@ -91,7 +91,7 @@ int sk_unshift(STACK *st,char *data);
char
*
sk_shift
(
STACK
*
st
);
char
*
sk_pop
(
STACK
*
st
);
void
sk_zero
(
STACK
*
st
);
void
sk_set_cmp_func
(
STACK
*
sk
,
int
(
*
c
)()
);
int
(
*
sk_set_cmp_func
(
STACK
*
sk
,
int
(
*
c
)()))(
);
STACK
*
sk_dup
(
STACK
*
st
);
#else
...
...
@@ -108,7 +108,7 @@ int sk_unshift();
char
*
sk_shift
();
char
*
sk_pop
();
void
sk_zero
();
void
sk_set_cmp_func
();
int
(
*
sk_set_cmp_func
())
();
STACK
*
sk_dup
();
#endif
...
...
openssl.doxy
浏览文件 @
eb90a483
PROJECT_NAME=OpenSSL
GENERATE_LATEX=no
OUTPUT_DIRECTORY=doxygen
INPUT=ssl
INPUT=ssl
include
FILE_PATTERNS=*.c *.h
RECURSIVE=yes
PREDEFINED=DOXYGEN
ssl/ssl.err
浏览文件 @
eb90a483
...
...
@@ -34,6 +34,7 @@
#define SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM 130
#define SSL_F_SSL3_CLIENT_HELLO 131
#define SSL_F_SSL3_CONNECT 132
#define SSL_F_SSL3_CTRL 213
#define SSL_F_SSL3_CTX_CTRL 133
#define SSL_F_SSL3_ENC 134
#define SSL_F_SSL3_GET_CERTIFICATE_REQUEST 135
...
...
@@ -61,8 +62,11 @@
#define SSL_F_SSL3_SETUP_KEY_BLOCK 157
#define SSL_F_SSL3_WRITE_BYTES 158
#define SSL_F_SSL3_WRITE_PENDING 159
#define SSL_F_SSL_ADD_CERT_DIR_TO_STACK 215
#define SSL_F_SSL_ADD_CERT_FILE_TO_STACK 216
#define SSL_F_SSL_BAD_METHOD 160
#define SSL_F_SSL_BYTES_TO_CIPHER_LIST 161
#define SSL_F_SSL_CERT_INSTANTIATE 214
#define SSL_F_SSL_CERT_NEW 162
#define SSL_F_SSL_CHECK_PRIVATE_KEY 163
#define SSL_F_SSL_CLEAR 164
...
...
@@ -113,8 +117,6 @@
#define SSL_F_TLS1_ENC 210
#define SSL_F_TLS1_SETUP_KEY_BLOCK 211
#define SSL_F_WRITE_PENDING 212
#define SSL_F_SSL3_CTRL 213
#define SSL_F_SSL_CERT_INSTANTIATE 214
/* Reason codes. */
#define SSL_R_APP_DATA_IN_HANDSHAKE 100
...
...
@@ -216,6 +218,7 @@
#define SSL_R_NULL_SSL_METHOD_PASSED 196
#define SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED 197
#define SSL_R_PACKET_LENGTH_TOO_LONG 198
#define SSL_R_PATH_TOO_LONG 270
#define SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE 199
#define SSL_R_PEER_ERROR 200
#define SSL_R_PEER_ERROR_CERTIFICATE 201
...
...
ssl/ssl.h
浏览文件 @
eb90a483
...
...
@@ -859,6 +859,8 @@ int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, char *file, int type);
int
SSL_CTX_use_PrivateKey_file
(
SSL_CTX
*
ctx
,
char
*
file
,
int
type
);
int
SSL_CTX_use_certificate_file
(
SSL_CTX
*
ctx
,
char
*
file
,
int
type
);
STACK
*
SSL_load_client_CA_file
(
char
*
file
);
int
SSL_add_cert_file_to_stack
(
STACK
*
stackCAs
,
const
char
*
file
);
int
SSL_add_cert_dir_to_stack
(
STACK
*
stackCAs
,
const
char
*
dir
);
#endif
void
ERR_load_SSL_strings
(
void
);
...
...
@@ -1111,6 +1113,8 @@ int SSL_CTX_use_RSAPrivateKey_file();
int
SSL_CTX_use_PrivateKey_file
();
int
SSL_CTX_use_certificate_file
();
STACK
*
SSL_load_client_CA_file
();
int
SSL_add_cert_file_to_stack
();
int
SSL_add_cert_dir_to_stack
();
#endif
void
ERR_load_SSL_strings
();
...
...
@@ -1317,6 +1321,7 @@ void SSL_set_tmp_dh_callback();
#define SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM 130
#define SSL_F_SSL3_CLIENT_HELLO 131
#define SSL_F_SSL3_CONNECT 132
#define SSL_F_SSL3_CTRL 213
#define SSL_F_SSL3_CTX_CTRL 133
#define SSL_F_SSL3_ENC 134
#define SSL_F_SSL3_GET_CERTIFICATE_REQUEST 135
...
...
@@ -1344,8 +1349,11 @@ void SSL_set_tmp_dh_callback();
#define SSL_F_SSL3_SETUP_KEY_BLOCK 157
#define SSL_F_SSL3_WRITE_BYTES 158
#define SSL_F_SSL3_WRITE_PENDING 159
#define SSL_F_SSL_ADD_CERT_DIR_TO_STACK 215
#define SSL_F_SSL_ADD_CERT_FILE_TO_STACK 216
#define SSL_F_SSL_BAD_METHOD 160
#define SSL_F_SSL_BYTES_TO_CIPHER_LIST 161
#define SSL_F_SSL_CERT_INSTANTIATE 214
#define SSL_F_SSL_CERT_NEW 162
#define SSL_F_SSL_CHECK_PRIVATE_KEY 163
#define SSL_F_SSL_CLEAR 164
...
...
@@ -1396,8 +1404,6 @@ void SSL_set_tmp_dh_callback();
#define SSL_F_TLS1_ENC 210
#define SSL_F_TLS1_SETUP_KEY_BLOCK 211
#define SSL_F_WRITE_PENDING 212
#define SSL_F_SSL3_CTRL 213
#define SSL_F_SSL_CERT_INSTANTIATE 214
/* Reason codes. */
#define SSL_R_APP_DATA_IN_HANDSHAKE 100
...
...
@@ -1499,6 +1505,7 @@ void SSL_set_tmp_dh_callback();
#define SSL_R_NULL_SSL_METHOD_PASSED 196
#define SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED 197
#define SSL_R_PACKET_LENGTH_TOO_LONG 198
#define SSL_R_PATH_TOO_LONG 270
#define SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE 199
#define SSL_R_PEER_ERROR 200
#define SSL_R_PEER_ERROR_CERTIFICATE 201
...
...
ssl/ssl_cert.c
浏览文件 @
eb90a483
/* ssl/ssl_cert.c */
/*
! \file
ssl/ssl_cert.c */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
...
...
@@ -57,6 +57,8 @@
*/
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
#include "objects.h"
#include "bio.h"
#include "pem.h"
...
...
@@ -100,8 +102,7 @@ CERT *ssl_cert_new()
return
(
ret
);
}
void
ssl_cert_free
(
c
)
CERT
*
c
;
void
ssl_cert_free
(
CERT
*
c
)
{
int
i
;
...
...
@@ -165,17 +166,13 @@ int ssl_cert_instantiate(CERT **o, CERT *d)
return
(
1
);
}
int
ssl_set_cert_type
(
c
,
type
)
CERT
*
c
;
int
type
;
int
ssl_set_cert_type
(
CERT
*
c
,
int
type
)
{
c
->
cert_type
=
type
;
return
(
1
);
}
int
ssl_verify_cert_chain
(
s
,
sk
)
SSL
*
s
;
STACK
*
sk
;
int
ssl_verify_cert_chain
(
SSL
*
s
,
STACK
*
sk
)
{
X509
*
x
;
int
i
;
...
...
@@ -208,9 +205,7 @@ STACK *sk;
return
(
i
);
}
static
void
set_client_CA_list
(
ca_list
,
list
)
STACK
**
ca_list
;
STACK
*
list
;
static
void
set_client_CA_list
(
STACK
**
ca_list
,
STACK
*
list
)
{
if
(
*
ca_list
!=
NULL
)
sk_pop_free
(
*
ca_list
,
X509_NAME_free
);
...
...
@@ -218,8 +213,7 @@ STACK *list;
*
ca_list
=
list
;
}
STACK
*
SSL_dup_CA_list
(
sk
)
STACK
*
sk
;
STACK
*
SSL_dup_CA_list
(
STACK
*
sk
)
{
int
i
;
STACK
*
ret
;
...
...
@@ -238,28 +232,22 @@ STACK *sk;
return
(
ret
);
}
void
SSL_set_client_CA_list
(
s
,
list
)
SSL
*
s
;
STACK
*
list
;
void
SSL_set_client_CA_list
(
SSL
*
s
,
STACK
*
list
)
{
set_client_CA_list
(
&
(
s
->
client_CA
),
list
);
}
void
SSL_CTX_set_client_CA_list
(
ctx
,
list
)
SSL_CTX
*
ctx
;
STACK
*
list
;
void
SSL_CTX_set_client_CA_list
(
SSL_CTX
*
ctx
,
STACK
*
list
)
{
set_client_CA_list
(
&
(
ctx
->
client_CA
),
list
);
}
STACK
*
SSL_CTX_get_client_CA_list
(
ctx
)
SSL_CTX
*
ctx
;
STACK
*
SSL_CTX_get_client_CA_list
(
SSL_CTX
*
ctx
)
{
return
(
ctx
->
client_CA
);
}
STACK
*
SSL_get_client_CA_list
(
s
)
SSL
*
s
;
STACK
*
SSL_get_client_CA_list
(
SSL
*
s
)
{
if
(
s
->
type
==
SSL_ST_CONNECT
)
{
/* we are in the client */
...
...
@@ -278,9 +266,7 @@ SSL *s;
}
}
static
int
add_client_CA
(
sk
,
x
)
STACK
**
sk
;
X509
*
x
;
static
int
add_client_CA
(
STACK
**
sk
,
X509
*
x
)
{
X509_NAME
*
name
;
...
...
@@ -299,29 +285,31 @@ X509 *x;
return
(
1
);
}
int
SSL_add_client_CA
(
ssl
,
x
)
SSL
*
ssl
;
X509
*
x
;
int
SSL_add_client_CA
(
SSL
*
ssl
,
X509
*
x
)
{
return
(
add_client_CA
(
&
(
ssl
->
client_CA
),
x
));
}
int
SSL_CTX_add_client_CA
(
ctx
,
x
)
SSL_CTX
*
ctx
;
X509
*
x
;
int
SSL_CTX_add_client_CA
(
SSL_CTX
*
ctx
,
X509
*
x
)
{
return
(
add_client_CA
(
&
(
ctx
->
client_CA
),
x
));
}
static
int
name_cmp
(
a
,
b
)
X509_NAME
**
a
,
**
b
;
static
int
name_cmp
(
X509_NAME
**
a
,
X509_NAME
**
b
)
{
return
(
X509_NAME_cmp
(
*
a
,
*
b
));
}
#ifndef NO_STDIO
STACK
*
SSL_load_client_CA_file
(
file
)
char
*
file
;
/*!
* Load CA certs from a file into a ::STACK. Note that it is somewhat misnamed;
* it doesn't really have anything to do with clients (except that a common use
* for a stack of CAs is to send it to the client). Actually, it doesn't have
* much to do with CAs, either, since it will load any old cert.
* \param file the file containing one or more certs.
* \return a ::STACK containing the certs.
*/
STACK
*
SSL_load_client_CA_file
(
char
*
file
)
{
BIO
*
in
;
X509
*
x
=
NULL
;
...
...
@@ -372,3 +360,101 @@ err:
}
#endif
/*!
* Add a file of certs to a stack.
* \param stack the stack to add to.
* \param file the file to add from. All certs in this file that are not
* already in the stack will be added.
* \return 1 for success, 0 for failure. Note that in the case of failure some
* certs may have been added to \c stack.
*/
int
SSL_add_cert_file_to_stack
(
STACK
*
stack
,
const
char
*
file
)
{
BIO
*
in
;
X509
*
x
=
NULL
;
X509_NAME
*
xn
=
NULL
;
int
ret
=
1
;
int
(
*
oldcmp
)();
oldcmp
=
sk_set_cmp_func
(
stack
,
name_cmp
);
in
=
BIO_new
(
BIO_s_file_internal
());
if
(
ret
==
NULL
||
in
==
NULL
)
{
SSLerr
(
SSL_F_SSL_ADD_CERT_FILE_TO_STACK
,
ERR_R_MALLOC_FAILURE
);
goto
err
;
}
if
(
!
BIO_read_filename
(
in
,
file
))
goto
err
;
for
(;;)
{
if
(
PEM_read_bio_X509
(
in
,
&
x
,
NULL
)
==
NULL
)
break
;
if
((
xn
=
X509_get_subject_name
(
x
))
==
NULL
)
goto
err
;
xn
=
X509_NAME_dup
(
xn
);
if
(
xn
==
NULL
)
goto
err
;
if
(
sk_find
(
stack
,(
char
*
)
xn
)
>=
0
)
X509_NAME_free
(
xn
);
else
sk_push
(
stack
,(
char
*
)
xn
);
}
if
(
0
)
{
err:
ret
=
0
;
}
if
(
in
!=
NULL
)
BIO_free
(
in
);
if
(
x
!=
NULL
)
X509_free
(
x
);
sk_set_cmp_func
(
stack
,
oldcmp
);
return
ret
;
}
/*!
* Add a directory of certs to a stack.
* \param stack the stack to append to.
* \param dir the directory to append from. All files in this directory will be
* examined as potential certs. Any that are acceptable to
* SSL_add_cert_file_to_stack() that are not already in the stack will be
* included.
* \return 1 for success, 0 for failure. Note that in the case of failure some
* certs may have been added to \c stack.
*/
int
SSL_add_cert_dir_to_stack
(
STACK
*
stack
,
const
char
*
dir
)
{
DIR
*
d
=
opendir
(
dir
);
struct
dirent
*
dstruct
;
/* Note that a side effect is that the CAs will be sorted by name */
if
(
!
d
)
{
SSLerr
(
SSL_F_SSL_ADD_CERT_DIR_TO_STACK
,
ERR_R_MALLOC_FAILURE
);
return
0
;
}
while
((
dstruct
=
readdir
(
d
)))
{
char
buf
[
1024
];
if
(
strlen
(
dir
)
+
strlen
(
dstruct
->
d_name
)
+
2
>
sizeof
buf
)
{
SSLerr
(
SSL_F_SSL_ADD_CERT_DIR_TO_STACK
,
SSL_R_PATH_TOO_LONG
);
return
0
;
}
sprintf
(
buf
,
"%s/%s"
,
dir
,
dstruct
->
d_name
);
if
(
!
SSL_add_cert_file_to_stack
(
stack
,
buf
))
return
0
;
}
return
1
;
}
ssl/ssl_err.c
浏览文件 @
eb90a483
...
...
@@ -96,6 +96,7 @@ static ERR_STRING_DATA SSL_str_functs[]=
{
ERR_PACK
(
0
,
SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM
,
0
),
"SSL3_CHECK_CERT_AND_ALGORITHM"
},
{
ERR_PACK
(
0
,
SSL_F_SSL3_CLIENT_HELLO
,
0
),
"SSL3_CLIENT_HELLO"
},
{
ERR_PACK
(
0
,
SSL_F_SSL3_CONNECT
,
0
),
"SSL3_CONNECT"
},
{
ERR_PACK
(
0
,
SSL_F_SSL3_CTRL
,
0
),
"SSL3_CTRL"
},
{
ERR_PACK
(
0
,
SSL_F_SSL3_CTX_CTRL
,
0
),
"SSL3_CTX_CTRL"
},
{
ERR_PACK
(
0
,
SSL_F_SSL3_ENC
,
0
),
"SSL3_ENC"
},
{
ERR_PACK
(
0
,
SSL_F_SSL3_GET_CERTIFICATE_REQUEST
,
0
),
"SSL3_GET_CERTIFICATE_REQUEST"
},
...
...
@@ -123,8 +124,11 @@ static ERR_STRING_DATA SSL_str_functs[]=
{
ERR_PACK
(
0
,
SSL_F_SSL3_SETUP_KEY_BLOCK
,
0
),
"SSL3_SETUP_KEY_BLOCK"
},
{
ERR_PACK
(
0
,
SSL_F_SSL3_WRITE_BYTES
,
0
),
"SSL3_WRITE_BYTES"
},
{
ERR_PACK
(
0
,
SSL_F_SSL3_WRITE_PENDING
,
0
),
"SSL3_WRITE_PENDING"
},
{
ERR_PACK
(
0
,
SSL_F_SSL_ADD_CERT_DIR_TO_STACK
,
0
),
"SSL_add_cert_dir_to_stack"
},
{
ERR_PACK
(
0
,
SSL_F_SSL_ADD_CERT_FILE_TO_STACK
,
0
),
"SSL_add_cert_file_to_stack"
},
{
ERR_PACK
(
0
,
SSL_F_SSL_BAD_METHOD
,
0
),
"SSL_BAD_METHOD"
},
{
ERR_PACK
(
0
,
SSL_F_SSL_BYTES_TO_CIPHER_LIST
,
0
),
"SSL_BYTES_TO_CIPHER_LIST"
},
{
ERR_PACK
(
0
,
SSL_F_SSL_CERT_INSTANTIATE
,
0
),
"SSL_CERT_INSTANTIATE"
},
{
ERR_PACK
(
0
,
SSL_F_SSL_CERT_NEW
,
0
),
"SSL_CERT_NEW"
},
{
ERR_PACK
(
0
,
SSL_F_SSL_CHECK_PRIVATE_KEY
,
0
),
"SSL_check_private_key"
},
{
ERR_PACK
(
0
,
SSL_F_SSL_CLEAR
,
0
),
"SSL_clear"
},
...
...
@@ -175,8 +179,6 @@ static ERR_STRING_DATA SSL_str_functs[]=
{
ERR_PACK
(
0
,
SSL_F_TLS1_ENC
,
0
),
"TLS1_ENC"
},
{
ERR_PACK
(
0
,
SSL_F_TLS1_SETUP_KEY_BLOCK
,
0
),
"TLS1_SETUP_KEY_BLOCK"
},
{
ERR_PACK
(
0
,
SSL_F_WRITE_PENDING
,
0
),
"WRITE_PENDING"
},
{
ERR_PACK
(
0
,
SSL_F_SSL3_CTRL
,
0
),
"SSL3_CTRL"
},
{
ERR_PACK
(
0
,
SSL_F_SSL_CERT_INSTANTIATE
,
0
),
"SSL_CERT_INSTANTIATE"
},
{
0
,
NULL
},
};
...
...
@@ -281,6 +283,7 @@ static ERR_STRING_DATA SSL_str_reasons[]=
{
SSL_R_NULL_SSL_METHOD_PASSED
,
"null ssl method passed"
},
{
SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED
,
"old session cipher not returned"
},
{
SSL_R_PACKET_LENGTH_TOO_LONG
,
"packet length too long"
},
{
SSL_R_PATH_TOO_LONG
,
"path too long"
},
{
SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE
,
"peer did not return a certificate"
},
{
SSL_R_PEER_ERROR
,
"peer error"
},
{
SSL_R_PEER_ERROR_CERTIFICATE
,
"peer error certificate"
},
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录