Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
F
fuzzBackEnd
Overview
Overview
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
钱炳权
fuzzBackEnd
Commits
b66e695c
Commit
b66e695c
authored
May 14, 2024
by
钱炳权
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
kitty日志文件存入数据库成功
parent
41283d5e
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
102 additions
and
72 deletions
+102
-72
AflnetProperties.java
.../java/com/example/fuzzControll/conf/AflnetProperties.java
+10
-1
IntegrationPathProperties.java
.../example/fuzzControll/conf/IntegrationPathProperties.java
+1
-1
KittyProperties.java
...n/java/com/example/fuzzControll/conf/KittyProperties.java
+0
-15
CmdConstent.java
.../java/com/example/fuzzControll/constents/CmdConstent.java
+6
-5
AlfnetControler.java
.../com/example/fuzzControll/controller/AlfnetControler.java
+3
-7
KittyController.java
.../com/example/fuzzControll/controller/KittyController.java
+1
-2
AflnetDataController.java
...troll/controller/dataController/AflnetDataController.java
+2
-2
AflnetMapper.java
...in/java/com/example/fuzzControll/mapper/AflnetMapper.java
+1
-1
AflnetPersistenceService.java
...xample/fuzzControll/service/AflnetPersistenceService.java
+1
-3
AflnetPersistenceServiceImpl.java
...zzControll/service/impl/AflnetPersistenceServiceImpl.java
+3
-4
SeedFileServiceImpl.java
...xample/fuzzControll/service/impl/SeedFileServiceImpl.java
+2
-2
TestServiceImpl.java
...om/example/fuzzControll/service/impl/TestServiceImpl.java
+43
-4
websocketClientServiceImpl.java
...fuzzControll/service/impl/websocketClientServiceImpl.java
+2
-2
CmdTools.java
...rc/main/java/com/example/fuzzControll/tools/CmdTools.java
+5
-5
GlobalParameters.java
...java/com/example/fuzzControll/tools/GlobalParameters.java
+18
-0
SqlTools.java
...rc/main/java/com/example/fuzzControll/tools/SqlTools.java
+0
-14
application-dev.yml
fuzzIntegration/src/main/resources/application-dev.yml
+3
-3
application.yml
fuzzIntegration/src/main/resources/application.yml
+1
-1
No files found.
fuzzIntegration/src/main/java/com/example/fuzzControll/conf/AflnetProperties.java
View file @
b66e695c
...
...
@@ -3,11 +3,20 @@ package com.example.fuzzControll.conf;
import
org.springframework.boot.context.properties.ConfigurationProperties
;
import
org.springframework.stereotype.Component
;
@Component
(
"
seed
Properties"
)
@Component
(
"
Aflnet
Properties"
)
@ConfigurationProperties
(
prefix
=
"aflnet"
)
public
class
AflnetProperties
{
String
seedPath
;
String
outputPath
;
String
aflnetPath
;
public
String
getAflnetPath
()
{
return
aflnetPath
;
}
public
void
setAflnetPath
(
String
aflnetPath
)
{
this
.
aflnetPath
=
aflnetPath
;
}
public
String
getOutputPath
()
{
return
outputPath
;
...
...
fuzzIntegration/src/main/java/com/example/fuzzControll/conf/IntegrationPathProperties.java
View file @
b66e695c
...
...
@@ -3,7 +3,7 @@ package com.example.fuzzControll.conf;
import
org.springframework.boot.context.properties.ConfigurationProperties
;
import
org.springframework.stereotype.Component
;
@Component
(
"PathProperties"
)
@Component
(
"
Integration
PathProperties"
)
@ConfigurationProperties
(
prefix
=
"integrationpath"
)
public
class
IntegrationPathProperties
{
String
webSocketUri
;
...
...
fuzzIntegration/src/main/java/com/example/fuzzControll/conf/KittyProperties.java
View file @
b66e695c
...
...
@@ -15,24 +15,9 @@ public class KittyProperties {
String
stagesHttp
;
String
reportHttp
;
String
mutationPath
;
String
aflnetPath
;
String
outputPath
;
public
String
getOutputPath
()
{
return
outputPath
;
}
public
void
setOutputPath
(
String
outputPath
)
{
this
.
outputPath
=
outputPath
;
}
public
String
getAflnetPath
()
{
return
aflnetPath
;
}
public
void
setAflnetPath
(
String
aflnetPath
)
{
this
.
aflnetPath
=
aflnetPath
;
}
public
String
getMutationPath
()
{
return
mutationPath
;
...
...
fuzzIntegration/src/main/java/com/example/fuzzControll/constents/CmdConstent.java
View file @
b66e695c
...
...
@@ -2,17 +2,18 @@ package com.example.fuzzControll.constents;
import
com.example.fuzzControll.conf.SpringContextUtil
;
import
com.example.fuzzControll.conf.KittyProperties
;
import
com.example.fuzzControll.tools.GlobalParameters
;
public
class
CmdConstent
{
static
KittyProperties
kittyProperties
=
(
KittyProperties
)
SpringContextUtil
.
getBean
(
"kittyProperties"
);
public
static
final
String
GET_FILE_NAME
=
"ls -h "
;
public
static
final
String
DELETE_FILE
=
"rm -r "
;
public
static
final
String
COUNT_FILE
=
"ls -l | grep \"^-\" | wc -l"
;
public
static
final
String
COUNT_DIR
=
"ls -l | grep \"^d\" | wc -l"
;
public
static
final
String
RUN_AFLNET_BEFORE
=
"afl-fuzz -d -i "
+
kitty
Properties
.
getAflnetPath
()
+
"aflnet/tutorials/live555/in-rtsp -o "
+
kitty
Properties
.
getOutputPath
();
public
static
final
String
RUN_AFLNET_AFTER
=
" -x "
+
kitty
Properties
.
getAflnetPath
()
+
"aflnet/tutorials/live555/rtsp.dict "
;
public
static
final
String
RUN_AFLNET_BEFORE
=
"afl-fuzz -d -i "
+
GlobalParameters
.
aflnet
Properties
.
getAflnetPath
()
+
"aflnet/tutorials/live555/in-rtsp -o "
+
GlobalParameters
.
aflnet
Properties
.
getOutputPath
();
public
static
final
String
RUN_AFLNET_AFTER
=
" -x "
+
GlobalParameters
.
aflnet
Properties
.
getAflnetPath
()
+
"aflnet/tutorials/live555/rtsp.dict "
;
public
static
final
String
RUN_PING
=
"ping www.baidu.com"
;
public
static
final
String
RUN_ZIP_FILE
=
"zip -r "
;
}
fuzzIntegration/src/main/java/com/example/fuzzControll/controller/
Tes
tControler.java
→
fuzzIntegration/src/main/java/com/example/fuzzControll/controller/
Alfne
tControler.java
View file @
b66e695c
...
...
@@ -13,16 +13,13 @@ import org.springframework.web.bind.annotation.RequestMapping;
import
org.springframework.web.bind.annotation.RequestMethod
;
import
org.springframework.web.bind.annotation.RestController
;
import
java.util.Arrays
;
import
java.util.concurrent.CountDownLatch
;
/**
* aflnet测试控制
*/
@Slf4j
@RestController
@RequestMapping
(
"/test"
)
public
class
Tes
tControler
{
public
class
Alfne
tControler
{
@Autowired
TestService
service
;
...
...
@@ -33,13 +30,12 @@ public class TestControler {
public
AjaxResult
start
(
@RequestBody
final
CmdStartParams
cmdStartParams
)
{
//todo 捕获子线程错误
try
{
Thread
alfnet
=
new
Thread
(
new
Runnable
()
{
new
Thread
(
new
Runnable
()
{
@Override
public
void
run
()
{
service
.
testStart
(
cmdStartParams
);
}
});
alfnet
.
start
();
}).
start
();
}
catch
(
Exception
e
)
{
if
(
e
instanceof
AflnetException
||
e
instanceof
CmdException
){
log
.
error
(((
BaseException
)
e
).
getDefaultMessage
());
...
...
fuzzIntegration/src/main/java/com/example/fuzzControll/controller/
TestClass
Controller.java
→
fuzzIntegration/src/main/java/com/example/fuzzControll/controller/
Kitty
Controller.java
View file @
b66e695c
...
...
@@ -15,7 +15,6 @@ import org.springframework.web.bind.annotation.RequestMapping;
import
org.springframework.web.bind.annotation.RequestMethod
;
import
org.springframework.web.bind.annotation.RestController
;
import
java.util.Arrays
;
import
java.util.List
;
import
java.util.Map
;
...
...
@@ -25,7 +24,7 @@ import java.util.Map;
@Slf4j
@RestController
@RequestMapping
(
"/testClass"
)
public
class
TestClass
Controller
{
public
class
Kitty
Controller
{
@Autowired
GenerateMethodService
generateMethodService
;
@Autowired
...
...
fuzzIntegration/src/main/java/com/example/fuzzControll/controller/dataController/AflnetDataController.java
View file @
b66e695c
...
...
@@ -10,6 +10,6 @@ import org.springframework.web.bind.annotation.RestController;
@RequestMapping
(
"/aflnet"
)
@Slf4j
public
class
AflnetDataController
{
@Autowired
AflnetPersistenceService
aflnetPersistenceService
;
//
@Autowired
//
AflnetPersistenceService aflnetPersistenceService;
}
fuzzIntegration/src/main/java/com/example/fuzzControll/mapper/AflnetMapper.java
View file @
b66e695c
...
...
@@ -17,5 +17,5 @@ public interface AflnetMapper {
/**
* 存储alfnet测试结果
*/
void
aflnetOutputBackup
(
AflnetResult
aflnetResult
);
int
aflnetOutputBackup
(
AflnetResult
aflnetResult
);
}
fuzzIntegration/src/main/java/com/example/fuzzControll/service/AflnetPersistenceService.java
View file @
b66e695c
package
com
.
example
.
fuzzControll
.
service
;
import
com.example.fuzzControll.pojo.vo.AflnetResult
;
public
interface
AflnetPersistenceService
{
public
void
aflnetResultBackup
(
String
filename
);
public
int
aflnetResultBackup
(
String
filename
);
}
fuzzIntegration/src/main/java/com/example/fuzzControll/service/impl/AflnetPersistenceServiceImpl.java
View file @
b66e695c
...
...
@@ -7,17 +7,16 @@ import com.example.fuzzControll.tools.FileTools;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
@Service
@Slf4j
@Service
(
"AflnetPersistenceService"
)
public
class
AflnetPersistenceServiceImpl
implements
AflnetPersistenceService
{
@Autowired
AflnetMapper
AflnetMapper
;
FileTools
fileTools
=
new
FileTools
();
@Override
public
void
aflnetResultBackup
(
String
filename
)
{
public
int
aflnetResultBackup
(
String
filename
)
{
//todo 需要传入任务id
AflnetResult
result
=
new
AflnetResult
(
1
,
fileTools
.
fileReadAndBackup
(
filename
),
filename
);
AflnetMapper
.
aflnetOutputBackup
(
result
);
return
AflnetMapper
.
aflnetOutputBackup
(
result
);
}
}
fuzzIntegration/src/main/java/com/example/fuzzControll/service/impl/SeedFileServiceImpl.java
View file @
b66e695c
package
com
.
example
.
fuzzControll
.
service
.
impl
;
import
com.example.fuzzControll.conf.
Seed
Properties
;
import
com.example.fuzzControll.conf.
Aflnet
Properties
;
import
com.example.fuzzControll.constents.CmdConstent
;
import
com.example.fuzzControll.exception.CmdException
;
import
com.example.fuzzControll.exception.FileException
;
...
...
@@ -24,7 +24,7 @@ public class SeedFileServiceImpl implements SeedFileService {
CmdTools
cmdTools
=
new
CmdTools
();
FileTools
fileTools
=
new
FileTools
();
@Autowired
Seed
Properties
properties
;
Aflnet
Properties
properties
;
@Override
public
List
<
String
>
getSeedFiles
()
throws
CmdException
{
...
...
fuzzIntegration/src/main/java/com/example/fuzzControll/service/impl/TestServiceImpl.java
View file @
b66e695c
package
com
.
example
.
fuzzControll
.
service
.
impl
;
import
com.example.fuzzControll.conf.AflnetProperties
;
import
com.example.fuzzControll.conf.SpringContextUtil
;
import
com.example.fuzzControll.conf.KittyProperties
;
import
com.example.fuzzControll.constents.CmdConstent
;
import
com.example.fuzzControll.exception.AflnetException
;
import
com.example.fuzzControll.exception.CmdException
;
import
com.example.fuzzControll.pojo.vo.CmdStartParams
;
import
com.example.fuzzControll.service.AflnetPersistenceService
;
import
com.example.fuzzControll.service.TestService
;
import
com.example.fuzzControll.tools.CmdTools
;
import
com.example.fuzzControll.tools.GlobalParameters
;
import
com.example.fuzzControll.tools.TestControlTools
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
import
java.text.DateFormat
;
import
java.text.SimpleDateFormat
;
import
java.util.Date
;
import
java.util.List
;
import
java.util.concurrent.CountDownLatch
;
@Service
(
"testService"
)
@Slf4j
public
class
TestServiceImpl
implements
TestService
{
KittyProperties
kittyProperties
=
(
KittyProperties
)
SpringContextUtil
.
getBean
(
"kittyProperties"
);
CmdTools
cmdTools
=
new
CmdTools
();
@Autowired
AflnetPersistenceService
aflnetPersistenceService
;
@Autowired
AflnetProperties
aflnetProperties
;
//todo 不同服务不同端口
@Override
...
...
@@ -31,10 +40,12 @@ public class TestServiceImpl implements TestService {
String
cmd
=
cmdTools
.
parse
(
cmdStartParams
);
Date
date
=
new
Date
();
DateFormat
df
=
new
SimpleDateFormat
(
"yyyy-MM-dd-hh-mm-ss-"
);
String
outputPathName
=
df
.
format
(
date
)+
cmdStartParams
.
getProtopcol
()+
"-output"
;
String
finalCmd
=
CmdConstent
.
RUN_AFLNET_BEFORE
+
outputPathName
+
CmdConstent
.
RUN_AFLNET_AFTER
+
cmd
+
kittyProperties
.
getAflnetPath
()
+
"live555/testProgs/testOnDemandRTSPServer 8554"
;
String
outputFileName
=
df
.
format
(
date
)+
cmdStartParams
.
getProtopcol
()+
"-output"
;
String
finalCmd
=
CmdConstent
.
RUN_AFLNET_BEFORE
+
outputFileName
+
CmdConstent
.
RUN_AFLNET_AFTER
+
cmd
+
aflnetProperties
.
getAflnetPath
()
+
"live555/testProgs/testOnDemandRTSPServer 8554"
;
GlobalParameters
.
aflnetData
.
put
(
"aflnetName"
,
outputFileName
);
log
.
info
(
"The cmd is [{}]"
,
finalCmd
);
cmdTools
.
runProgramCmd
(
finalCmd
,
outputPathName
);
cmdTools
.
runProgramCmd
(
finalCmd
,
outputFileName
+
".zip"
);
}
...
...
@@ -42,5 +53,33 @@ public class TestServiceImpl implements TestService {
public
void
testStop
()
{
TestControlTools
.
setIsRunning
(
false
);
log
.
info
(
"Aflnet has been stopped ! "
);
try
{
new
Thread
(
new
Runnable
()
{
@Override
public
void
run
()
{
int
flag
=
0
;
String
fileName
=
GlobalParameters
.
aflnetData
.
get
(
"aflnetName"
);
String
fileZipName
=
fileName
+
".zip"
;
cmdTools
.
runCmd
(
CmdConstent
.
RUN_ZIP_FILE
+
fileZipName
+
" "
+
fileName
,
"zip file in testStart"
);
List
<
String
>
files
=
cmdTools
.
runCmd
(
CmdConstent
.
GET_FILE_NAME
+
aflnetProperties
.
getOutputPath
(),
"getSeedFiles"
);
while
(
files
.
contains
(
fileZipName
)
&&
flag
==
0
)
{
//当前存在压缩包才存入
flag
=
aflnetPersistenceService
.
aflnetResultBackup
(
fileZipName
);
}
/*清除生成的文件*/
try
{
cmdTools
.
runCmd
(
CmdConstent
.
DELETE_FILE
+
fileName
,
"delete file"
);
cmdTools
.
runCmd
(
CmdConstent
.
DELETE_FILE
+
fileZipName
,
"delete zipFile"
);
}
catch
(
CmdException
e
)
{
e
.
printStackTrace
();
log
.
error
(
"file delete failed!"
);
}
log
.
info
(
"kittyLog has been backuped!"
);
}
}).
start
();
}
catch
(
Exception
e
)
{
log
.
error
(
"AflnetBackup Error!"
);
e
.
printStackTrace
();
}
}
}
fuzzIntegration/src/main/java/com/example/fuzzControll/service/impl/websocketClientServiceImpl.java
View file @
b66e695c
package
com
.
example
.
fuzzControll
.
service
.
impl
;
import
com.example.fuzzControll.conf.PathProperties
;
import
com.example.fuzzControll.conf.
Integration
PathProperties
;
import
com.example.fuzzControll.service.websocketClientService
;
import
lombok.extern.slf4j.Slf4j
;
import
org.java_websocket.client.WebSocketClient
;
...
...
@@ -16,7 +16,7 @@ import java.net.URISyntaxException;
public
class
websocketClientServiceImpl
implements
websocketClientService
{
public
static
WebSocketClient
webSocketClient
=
null
;
@Autowired
PathProperties
properties
;
Integration
PathProperties
properties
;
@Override
public
void
connect
()
{
try
{
...
...
fuzzIntegration/src/main/java/com/example/fuzzControll/tools/CmdTools.java
View file @
b66e695c
package
com
.
example
.
fuzzControll
.
tools
;
import
com.alibaba.fastjson.JSONObject
;
import
com.example.fuzzControll.conf.AflnetProperties
;
import
com.example.fuzzControll.conf.SpringContextUtil
;
import
com.example.fuzzControll.constents.CmdConstent
;
import
com.example.fuzzControll.exception.AflnetException
;
import
com.example.fuzzControll.exception.CmdException
;
import
com.example.fuzzControll.mapper.KittyMapper
;
...
...
@@ -25,8 +27,6 @@ public class CmdTools {
Boolean
show
=
true
;
SqlTools
sqlTools
=
new
SqlTools
();
AflnetPersistenceService
AflnetPersistenceService
=
(
AflnetPersistenceService
)
SpringContextUtil
.
getBean
(
"AflnetPersistenceService"
);
/**
* 运行不需要后台运行cmd
*/
...
...
@@ -50,13 +50,12 @@ public class CmdTools {
* 运行需要后台运行cmd
* 通过websocket返回数据
*/
public
void
runProgramCmd
(
String
cmd
,
String
output
Path
Name
)
throws
AflnetException
{
public
void
runProgramCmd
(
String
cmd
,
String
output
File
Name
)
throws
AflnetException
{
try
{
Process
process
=
Runtime
.
getRuntime
().
exec
(
cmd
);
printMessageToWeb
(
process
.
getInputStream
());
printMessage
(
process
.
getErrorStream
(),
new
ArrayList
<
String
>());
process
.
waitFor
();
AflnetPersistenceService
.
aflnetResultBackup
(
outputPathName
);
log
.
info
(
"Aflnet cmd have been run."
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
...
...
@@ -80,7 +79,7 @@ public class CmdTools {
//todo 对于无法运行和数据较长的还需要观察
try
{
KittyResult
kittyResult
=
new
KittyResult
(
1
,
out
.
toString
(),
error
.
toString
());
sqlTools
.
kitty
Backup
(
kittyResult
);
GlobalParameters
.
kittyMapper
.
kittyResults
Backup
(
kittyResult
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
log
.
error
(
"kitty backup error!"
);
...
...
@@ -260,6 +259,7 @@ public class CmdTools {
if
(
cmdStartParams
.
getNetinfo
()
!=
""
&&
cmdStartParams
.
getNetinfo
()
!=
null
)
{
cmd
.
append
(
" -N "
+
cmdStartParams
.
getNetinfo
());
}
else
{
log
.
error
(
"There is no netinfo !"
);
throw
new
AflnetException
(
"There is no netinfo !"
);
}
if
(
cmdStartParams
.
getProtopcol
()
!=
""
)
{
...
...
fuzzIntegration/src/main/java/com/example/fuzzControll/tools/GlobalParameters.java
0 → 100644
View file @
b66e695c
package
com
.
example
.
fuzzControll
.
tools
;
import
com.example.fuzzControll.conf.AflnetProperties
;
import
com.example.fuzzControll.conf.KittyProperties
;
import
com.example.fuzzControll.conf.SpringContextUtil
;
import
com.example.fuzzControll.mapper.KittyMapper
;
import
com.example.fuzzControll.service.AflnetPersistenceService
;
import
java.util.concurrent.ConcurrentHashMap
;
public
class
GlobalParameters
{
public
static
ConcurrentHashMap
<
String
,
String
>
aflnetData
=
new
ConcurrentHashMap
<>();
//当前aflnet任务的数据
public
static
KittyMapper
kittyMapper
=
(
KittyMapper
)
SpringContextUtil
.
getBean
(
"KittyMapper"
);
public
static
KittyProperties
kittyProperties
=
(
KittyProperties
)
SpringContextUtil
.
getBean
(
"kittyProperties"
);
public
static
AflnetProperties
aflnetProperties
=
(
AflnetProperties
)
SpringContextUtil
.
getBean
(
"AflnetProperties"
);
public
static
AflnetPersistenceService
aflnetPersistenceService
=
(
AflnetPersistenceService
)
SpringContextUtil
.
getBean
(
"AflnetPersistenceService"
);
}
fuzzIntegration/src/main/java/com/example/fuzzControll/tools/SqlTools.java
deleted
100644 → 0
View file @
41283d5e
package
com
.
example
.
fuzzControll
.
tools
;
import
com.example.fuzzControll.conf.KittyProperties
;
import
com.example.fuzzControll.conf.SpringContextUtil
;
import
com.example.fuzzControll.mapper.KittyMapper
;
import
com.example.fuzzControll.pojo.vo.KittyResult
;
public
class
SqlTools
{
KittyMapper
kittyMapper
=
(
KittyMapper
)
SpringContextUtil
.
getBean
(
"KittyMapper"
);
public
void
kittyBackup
(
KittyResult
kittyResult
)
{
kittyMapper
.
kittyResultsBackup
(
kittyResult
);
}
}
fuzzIntegration/src/main/resources/application-dev.yml
View file @
b66e695c
...
...
@@ -21,10 +21,10 @@ logging:
aflnet
:
seedPath
:
"
/usr/fuzzenv/fuzzenv/aflnet/tutorials/live555/in-rtsp"
outputPath
:
"
D:/code/companyProjects/files"
#D:/code/companyProjects/files
kitty
:
outputPath
:
"
/home/"
#D:/code/companyProjects/files/
aflnetPath
:
"
/usr/fuzzenv/fuzzenv/"
#alfnet路径
outputPath
:
"
/home/"
#alfnet输出路径
kitty
:
path
:
"
/usr/fuzzenv/fuzzenv/fuzz50/kitty/renix/"
#kitty项目下的各协议生成模板python文件路径
venvPath
:
"
/usr/fuzzenv/fuzzenv/fuzz50/kitty/venv/bin/python"
methodPath
:
"
/usr/fuzzenv/fuzzenv/fuzz50/kitty/2020test/"
#kitty下变异方法路径
...
...
fuzzIntegration/src/main/resources/application.yml
View file @
b66e695c
...
...
@@ -5,6 +5,6 @@ spring:
active
:
dev
#默认为开发环境
server
:
port
:
810
2
port
:
810
3
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