Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
BC
public
linphone-desktop
Commits
59010084
Commit
59010084
authored
May 30, 2017
by
Sylvain Berfini
🐮
Browse files
Added ZRTP token authentication while in call
parent
a346aedd
Changes
15
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
315 additions
and
3 deletions
+315
-3
linphone-desktop/assets/images/call_chat_secure_hovered.svg
linphone-desktop/assets/images/call_chat_secure_hovered.svg
+15
-0
linphone-desktop/assets/images/call_chat_secure_normal.svg
linphone-desktop/assets/images/call_chat_secure_normal.svg
+15
-0
linphone-desktop/assets/images/call_chat_secure_pressed.svg
linphone-desktop/assets/images/call_chat_secure_pressed.svg
+15
-0
linphone-desktop/assets/images/call_chat_unsecure_hovered.svg
...hone-desktop/assets/images/call_chat_unsecure_hovered.svg
+15
-0
linphone-desktop/assets/images/call_chat_unsecure_normal.svg
linphone-desktop/assets/images/call_chat_unsecure_normal.svg
+15
-0
linphone-desktop/assets/images/call_chat_unsecure_pressed.svg
...hone-desktop/assets/images/call_chat_unsecure_pressed.svg
+15
-0
linphone-desktop/assets/languages/en.ts
linphone-desktop/assets/languages/en.ts
+20
-0
linphone-desktop/assets/languages/fr.ts
linphone-desktop/assets/languages/fr.ts
+20
-0
linphone-desktop/resources.qrc
linphone-desktop/resources.qrc
+6
-0
linphone-desktop/src/components/call/CallModel.cpp
linphone-desktop/src/components/call/CallModel.cpp
+51
-0
linphone-desktop/src/components/call/CallModel.hpp
linphone-desktop/src/components/call/CallModel.hpp
+23
-0
linphone-desktop/ui/views/App/Calls/Incall.js
linphone-desktop/ui/views/App/Calls/Incall.js
+1
-1
linphone-desktop/ui/views/App/Calls/Incall.qml
linphone-desktop/ui/views/App/Calls/Incall.qml
+94
-1
linphone-desktop/ui/views/App/Styles/Calls/CallStyle.qml
linphone-desktop/ui/views/App/Styles/Calls/CallStyle.qml
+9
-0
submodules/linphone
submodules/linphone
+1
-1
No files found.
linphone-desktop/assets/images/call_chat_secure_hovered.svg
0 → 100644
View file @
59010084
<?xml version="1.0" encoding="UTF-8"?>
<svg
width=
"10px"
height=
"14px"
viewBox=
"0 0 10 14"
version=
"1.1"
xmlns=
"http://www.w3.org/2000/svg"
xmlns:xlink=
"http://www.w3.org/1999/xlink"
>
<!-- Generator: Sketch 42 (36781) - http://www.bohemiancoding.com/sketch -->
<title>
chat_secure@x2
</title>
<desc>
Created with Sketch.
</desc>
<defs></defs>
<g
id=
"Symbols"
stroke=
"none"
stroke-width=
"1"
fill=
"none"
fill-rule=
"evenodd"
>
<g
id=
"chat_secure@x2"
>
<g
id=
"Group-2"
transform=
"translate(0.000000, 1.000000)"
>
<rect
id=
"Rectangle-4"
fill=
"#595759"
x=
"0"
y=
"4.33333322"
width=
"9.99999974"
height=
"8.66666644"
></rect>
<path
d=
"M7.99999979,11.3429854 L7.99999979,3.16521731 C7.99999979,1.41711606 6.65685407,0 4.99999987,0 C3.34314566,0 1.99999995,1.41711606 1.99999995,3.16521731 L1.99999995,11.3429854 L7.99999979,11.3429854 Z"
id=
"Oval-6"
stroke=
"#595759"
stroke-width=
"2"
></path>
</g>
</g>
</g>
</svg>
\ No newline at end of file
linphone-desktop/assets/images/call_chat_secure_normal.svg
0 → 100644
View file @
59010084
<?xml version="1.0" encoding="UTF-8"?>
<svg
width=
"10px"
height=
"14px"
viewBox=
"0 0 10 14"
version=
"1.1"
xmlns=
"http://www.w3.org/2000/svg"
xmlns:xlink=
"http://www.w3.org/1999/xlink"
>
<!-- Generator: Sketch 42 (36781) - http://www.bohemiancoding.com/sketch -->
<title>
chat_secure@x2
</title>
<desc>
Created with Sketch.
</desc>
<defs></defs>
<g
id=
"Symbols"
stroke=
"none"
stroke-width=
"1"
fill=
"none"
fill-rule=
"evenodd"
>
<g
id=
"chat_secure@x2"
>
<g
id=
"Group-2"
transform=
"translate(0.000000, 1.000000)"
>
<rect
id=
"Rectangle-4"
fill=
"#595759"
x=
"0"
y=
"4.33333322"
width=
"9.99999974"
height=
"8.66666644"
></rect>
<path
d=
"M7.99999979,11.3429854 L7.99999979,3.16521731 C7.99999979,1.41711606 6.65685407,0 4.99999987,0 C3.34314566,0 1.99999995,1.41711606 1.99999995,3.16521731 L1.99999995,11.3429854 L7.99999979,11.3429854 Z"
id=
"Oval-6"
stroke=
"#595759"
stroke-width=
"2"
></path>
</g>
</g>
</g>
</svg>
\ No newline at end of file
linphone-desktop/assets/images/call_chat_secure_pressed.svg
0 → 100644
View file @
59010084
<?xml version="1.0" encoding="UTF-8"?>
<svg
width=
"10px"
height=
"14px"
viewBox=
"0 0 10 14"
version=
"1.1"
xmlns=
"http://www.w3.org/2000/svg"
xmlns:xlink=
"http://www.w3.org/1999/xlink"
>
<!-- Generator: Sketch 42 (36781) - http://www.bohemiancoding.com/sketch -->
<title>
chat_secure@x2
</title>
<desc>
Created with Sketch.
</desc>
<defs></defs>
<g
id=
"Symbols"
stroke=
"none"
stroke-width=
"1"
fill=
"none"
fill-rule=
"evenodd"
>
<g
id=
"chat_secure@x2"
>
<g
id=
"Group-2"
transform=
"translate(0.000000, 1.000000)"
>
<rect
id=
"Rectangle-4"
fill=
"#595759"
x=
"0"
y=
"4.33333322"
width=
"9.99999974"
height=
"8.66666644"
></rect>
<path
d=
"M7.99999979,11.3429854 L7.99999979,3.16521731 C7.99999979,1.41711606 6.65685407,0 4.99999987,0 C3.34314566,0 1.99999995,1.41711606 1.99999995,3.16521731 L1.99999995,11.3429854 L7.99999979,11.3429854 Z"
id=
"Oval-6"
stroke=
"#595759"
stroke-width=
"2"
></path>
</g>
</g>
</g>
</svg>
\ No newline at end of file
linphone-desktop/assets/images/call_chat_unsecure_hovered.svg
0 → 100644
View file @
59010084
<?xml version="1.0" encoding="UTF-8"?>
<svg
width=
"10px"
height=
"16px"
viewBox=
"0 0 10 16"
version=
"1.1"
xmlns=
"http://www.w3.org/2000/svg"
xmlns:xlink=
"http://www.w3.org/1999/xlink"
>
<!-- Generator: Sketch 42 (36781) - http://www.bohemiancoding.com/sketch -->
<title>
chat_unsecure@x2
</title>
<desc>
Created with Sketch.
</desc>
<defs></defs>
<g
id=
"Symbols"
stroke=
"none"
stroke-width=
"1"
fill=
"none"
fill-rule=
"evenodd"
>
<g
id=
"chat_unsecure@x2"
>
<g
id=
"Group-2"
transform=
"translate(0.000000, 0.180000)"
>
<rect
id=
"Rectangle-4"
fill=
"#FF0000"
x=
"0"
y=
"7.13541656"
width=
"10"
height=
"8.66666667"
></rect>
<path
d=
"M7.74999979,3.88630432 C7.74999979,2.19283123 6.44882738,0.820000052 4.84374987,0.820000052 C3.23867236,0.820000052 1.93749995,2.19283123 1.93749995,3.88630432 L1.93749995,11.8085172"
id=
"Oval-6"
stroke=
"#FF0000"
stroke-width=
"2"
></path>
</g>
</g>
</g>
</svg>
\ No newline at end of file
linphone-desktop/assets/images/call_chat_unsecure_normal.svg
0 → 100644
View file @
59010084
<?xml version="1.0" encoding="UTF-8"?>
<svg
width=
"10px"
height=
"16px"
viewBox=
"0 0 10 16"
version=
"1.1"
xmlns=
"http://www.w3.org/2000/svg"
xmlns:xlink=
"http://www.w3.org/1999/xlink"
>
<!-- Generator: Sketch 42 (36781) - http://www.bohemiancoding.com/sketch -->
<title>
chat_unsecure@x2
</title>
<desc>
Created with Sketch.
</desc>
<defs></defs>
<g
id=
"Symbols"
stroke=
"none"
stroke-width=
"1"
fill=
"none"
fill-rule=
"evenodd"
>
<g
id=
"chat_unsecure@x2"
>
<g
id=
"Group-2"
transform=
"translate(0.000000, 0.180000)"
>
<rect
id=
"Rectangle-4"
fill=
"#FF0000"
x=
"0"
y=
"7.13541656"
width=
"10"
height=
"8.66666667"
></rect>
<path
d=
"M7.74999979,3.88630432 C7.74999979,2.19283123 6.44882738,0.820000052 4.84374987,0.820000052 C3.23867236,0.820000052 1.93749995,2.19283123 1.93749995,3.88630432 L1.93749995,11.8085172"
id=
"Oval-6"
stroke=
"#FF0000"
stroke-width=
"2"
></path>
</g>
</g>
</g>
</svg>
\ No newline at end of file
linphone-desktop/assets/images/call_chat_unsecure_pressed.svg
0 → 100644
View file @
59010084
<?xml version="1.0" encoding="UTF-8"?>
<svg
width=
"10px"
height=
"16px"
viewBox=
"0 0 10 16"
version=
"1.1"
xmlns=
"http://www.w3.org/2000/svg"
xmlns:xlink=
"http://www.w3.org/1999/xlink"
>
<!-- Generator: Sketch 42 (36781) - http://www.bohemiancoding.com/sketch -->
<title>
chat_unsecure@x2
</title>
<desc>
Created with Sketch.
</desc>
<defs></defs>
<g
id=
"Symbols"
stroke=
"none"
stroke-width=
"1"
fill=
"none"
fill-rule=
"evenodd"
>
<g
id=
"chat_unsecure@x2"
>
<g
id=
"Group-2"
transform=
"translate(0.000000, 0.180000)"
>
<rect
id=
"Rectangle-4"
fill=
"#FF0000"
x=
"0"
y=
"7.13541656"
width=
"10"
height=
"8.66666667"
></rect>
<path
d=
"M7.74999979,3.88630432 C7.74999979,2.19283123 6.44882738,0.820000052 4.84374987,0.820000052 C3.23867236,0.820000052 1.93749995,2.19283123 1.93749995,3.88630432 L1.93749995,11.8085172"
id=
"Oval-6"
stroke=
"#FF0000"
stroke-width=
"2"
></path>
</g>
</g>
</g>
</svg>
\ No newline at end of file
linphone-desktop/assets/languages/en.ts
View file @
59010084
...
...
@@ -731,6 +731,26 @@ Server url not configured.</translation>
<
source
>
pendingRequestLabel
<
/source
>
<
translation
>
Please
to
wait
,
a
request
is
pending
.
<
/translation
>
<
/message
>
<
message
>
<
source
>
Say
:
<
/source
>
<
translation
>
Say
:
<
/translation
>
<
/message
>
<
message
>
<
source
>
Your
correspondent
should
say
:
<
/source
>
<
translation
>
Your
correspondent
should
say
:
<
/translation
>
<
/message
>
<
message
>
<
source
>
Deny
<
/source
>
<
translation
>
DENY
<
/translation
>
<
/message
>
<
message
>
<
source
>
Accept
<
/source
>
<
translation
>
ACCEPT
<
/translation
>
<
/message
>
<
message
>
<
source
>
Confirm
the
following
SAS
with
peer
:
<
/source
>
<
translation
>
Confirm
the
following
SAS
with
peer
:
<
/translation
>
<
/message
>
<
/context
>
<
context
>
<
name
>
InviteFriends
<
/name
>
...
...
linphone-desktop/assets/languages/fr.ts
View file @
59010084
...
...
@@ -731,6 +731,26 @@ Url du serveur non configurée.</translation>
<
source
>
pendingRequestLabel
<
/source
>
<
translation
>
Merci
de
patienter
,
une
requête
est
en
attente
.
<
/translation
>
<
/message
>
<
message
>
<
source
>
Say
:
<
/source
>
<
translation
>
Dites
:
<
/translation
>
<
/message
>
<
message
>
<
source
>
Your
correspondent
should
say
:
<
/source
>
<
translation
>
Votre
interlocuteur
devrait
dire
:
<
/translation
>
<
/message
>
<
message
>
<
source
>
Deny
<
/source
>
<
translation
>
REJETER
<
/translation
>
<
/message
>
<
message
>
<
source
>
Accept
<
/source
>
<
translation
>
VALIDER
<
/translation
>
<
/message
>
<
message
>
<
source
>
Confirm
the
following
SAS
with
peer
:
<
/source
>
<
translation
>
Confirmez
le
SAS
suivant
avec
votre
interlocuteur
:
<
/translation
>
<
/message
>
<
/context
>
<
context
>
<
name
>
InviteFriends
<
/name
>
...
...
linphone-desktop/resources.qrc
View file @
59010084
...
...
@@ -26,6 +26,12 @@
<file>
assets/images/call_accept_hovered.svg
</file>
<file>
assets/images/call_accept_normal.svg
</file>
<file>
assets/images/call_accept_pressed.svg
</file>
<file>
assets/images/call_chat_secure_hovered.svg
</file>
<file>
assets/images/call_chat_secure_normal.svg
</file>
<file>
assets/images/call_chat_secure_pressed.svg
</file>
<file>
assets/images/call_chat_unsecure_hovered.svg
</file>
<file>
assets/images/call_chat_unsecure_normal.svg
</file>
<file>
assets/images/call_chat_unsecure_pressed.svg
</file>
<file>
assets/images/call_hovered.svg
</file>
<file>
assets/images/call_normal.svg
</file>
<file>
assets/images/call_pressed.svg
</file>
...
...
linphone-desktop/src/components/call/CallModel.cpp
View file @
59010084
...
...
@@ -263,6 +263,7 @@ void CallModel::handleCallStateChanged (const shared_ptr<linphone::Call> &call,
break
;
}
emit
securityUpdated
();
emit
statusChanged
(
getStatus
());
}
...
...
@@ -495,6 +496,56 @@ void CallModel::sendDtmf (const QString &dtmf) {
// -----------------------------------------------------------------------------
CallModel
::
CallEncryption
CallModel
::
getEncryption
()
const
{
shared_ptr
<
const
linphone
::
CallParams
>
params
=
mCall
->
getCurrentParams
();
linphone
::
MediaEncryption
encryption
=
params
->
getMediaEncryption
();
switch
(
encryption
)
{
case
linphone
::
MediaEncryptionSRTP
:
return
CallEncryptionSRTP
;
case
linphone
::
MediaEncryptionZRTP
:
return
CallEncryptionZRTP
;
case
linphone
::
MediaEncryptionDTLS
:
return
CallEncryptionDTLS
;
case
linphone
::
MediaEncryptionNone
:
default:
return
CallEncryptionNone
;
}
}
bool
CallModel
::
isSecured
()
const
{
shared_ptr
<
const
linphone
::
CallParams
>
params
=
mCall
->
getCurrentParams
();
linphone
::
MediaEncryption
encryption
=
params
->
getMediaEncryption
();
return
(
encryption
==
linphone
::
MediaEncryptionZRTP
&&
mCall
->
getAuthenticationTokenVerified
())
||
encryption
==
linphone
::
MediaEncryptionSRTP
||
encryption
==
linphone
::
MediaEncryptionDTLS
;
}
QString
CallModel
::
getLocalSAS
()
const
{
QString
token
=
mCall
->
getAuthenticationToken
().
c_str
();
linphone
::
CallDir
direction
=
mCall
->
getDir
();
if
(
direction
==
linphone
::
CallDirIncoming
)
{
return
token
.
left
(
2
).
toUpper
();
}
else
{
return
token
.
right
(
2
).
toUpper
();
}
}
QString
CallModel
::
getRemoteSAS
()
const
{
QString
token
=
mCall
->
getAuthenticationToken
().
c_str
();
linphone
::
CallDir
direction
=
mCall
->
getDir
();
if
(
direction
==
linphone
::
CallDirIncoming
)
{
return
token
.
right
(
2
).
toUpper
();
}
else
{
return
token
.
left
(
2
).
toUpper
();
}
}
void
CallModel
::
verifyAuthenticationToken
(
bool
verify
)
{
mCall
->
setAuthenticationTokenVerified
(
verify
);
emit
securityUpdated
();
}
// -----------------------------------------------------------------------------
QVariantList
CallModel
::
getAudioStats
()
const
{
return
mAudioStats
;
}
...
...
linphone-desktop/src/components/call/CallModel.hpp
View file @
59010084
...
...
@@ -55,6 +55,11 @@ class CallModel : public QObject {
Q_PROPERTY
(
QVariantList
audioStats
READ
getAudioStats
NOTIFY
statsUpdated
);
Q_PROPERTY
(
QVariantList
videoStats
READ
getVideoStats
NOTIFY
statsUpdated
);
Q_PROPERTY
(
CallEncryption
encryption
READ
getEncryption
NOTIFY
securityUpdated
);
Q_PROPERTY
(
bool
isSecured
READ
isSecured
NOTIFY
securityUpdated
);
Q_PROPERTY
(
QString
localSAS
READ
getLocalSAS
NOTIFY
securityUpdated
);
Q_PROPERTY
(
QString
remoteSAS
READ
getRemoteSAS
NOTIFY
securityUpdated
);
public:
enum
CallStatus
{
CallStatusConnected
,
...
...
@@ -67,6 +72,15 @@ public:
Q_ENUM
(
CallStatus
);
enum
CallEncryption
{
CallEncryptionNone
,
CallEncryptionSRTP
,
CallEncryptionZRTP
,
CallEncryptionDTLS
};
Q_ENUM
(
CallEncryption
);
CallModel
(
std
::
shared_ptr
<
linphone
::
Call
>
linphoneCall
);
~
CallModel
();
...
...
@@ -100,6 +114,8 @@ public:
Q_INVOKABLE
void
sendDtmf
(
const
QString
&
dtmf
);
Q_INVOKABLE
void
verifyAuthenticationToken
(
bool
verify
);
signals:
void
callErrorChanged
(
const
QString
&
callError
);
void
isInConferenceChanged
(
bool
status
);
...
...
@@ -108,6 +124,7 @@ signals:
void
statsUpdated
();
void
statusChanged
(
CallStatus
status
);
void
videoRequested
();
void
securityUpdated
();
private:
void
handleCallStateChanged
(
const
std
::
shared_ptr
<
linphone
::
Call
>
&
call
,
linphone
::
CallState
state
);
...
...
@@ -145,10 +162,16 @@ private:
bool
getRecording
()
const
;
CallEncryption
getEncryption
()
const
;
bool
isSecured
()
const
;
QString
getLocalSAS
()
const
;
QString
getRemoteSAS
()
const
;
QVariantList
getAudioStats
()
const
;
QVariantList
getVideoStats
()
const
;
void
updateStats
(
const
std
::
shared_ptr
<
const
linphone
::
CallStats
>
&
callStats
,
QVariantList
&
statsList
);
QString
iceStateToString
(
linphone
::
IceState
state
)
const
;
bool
mIsInConference
=
false
;
...
...
linphone-desktop/ui/views/App/Calls/Incall.js
View file @
59010084
...
...
@@ -9,7 +9,7 @@
// =============================================================================
function
computeAvatarSize
(
maxSize
)
{
var
height
=
container
.
height
var
height
=
zrtp
.
visible
?
container
.
height
-
zrtp
.
height
:
container
.
height
var
width
=
container
.
width
var
size
=
height
<
maxSize
&&
height
>
0
?
height
:
maxSize
...
...
linphone-desktop/ui/views/App/Calls/Incall.qml
View file @
59010084
...
...
@@ -102,6 +102,13 @@ Rectangle {
onClicked
:
telKeypad
.
visible
=
!
telKeypad
.
visible
}
ActionButton
{
id
:
callSecure
icon
:
incall
.
call
.
isSecured
?
'
call_chat_secure
'
:
'
call_chat_unsecure
'
onClicked
:
incall
.
call
.
encryption
===
CallModel
.
CallEncryptionZRTP
?
zrtp
.
visible
=
true
:
zrtp
.
visible
=
false
}
}
ContactDescription
{
...
...
@@ -228,7 +235,7 @@ Rectangle {
Camera
{
call
:
incall
.
call
height
:
container
.
height
height
:
zrtp
.
visible
?
container
.
height
-
zrtp
.
height
:
container
.
height
width
:
container
.
width
}
}
...
...
@@ -242,6 +249,92 @@ Rectangle {
}
}
Item
{
id
:
zrtp
height
:
CallStyle
.
zrtpArea
.
height
visible
:
false
Layout.fillWidth
:
true
anchors.top
:
container
.
bottom
Layout.margins
:
CallStyle
.
container
.
margins
GridLayout
{
anchors.centerIn
:
parent
columns
:
1
Text
{
Layout.fillWidth
:
true
anchors.horizontalCenter
:
parent
.
horizontalCenter
horizontalAlignment
:
Text
.
AlignHCenter
verticalAlignment
:
Text
.
AlignVCenter
text
:
qsTr
(
"
Confirm the following SAS with peer:
"
)
elide
:
Text
.
ElideRight
font.pointSize
:
CallStyle
.
zrtpArea
.
fontSize
font.bold
:
true
color
:
Colors
.
j
}
RowLayout
{
anchors.horizontalCenter
:
parent
.
horizontalCenter
spacing
:
CallStyle
.
zrtpArea
.
vu
.
spacing
Layout.fillWidth
:
true
Text
{
text
:
qsTr
(
"
Say:
"
)
font.pointSize
:
CallStyle
.
zrtpArea
.
fontSize
color
:
Colors
.
j
}
Text
{
text
:
incall
.
call
.
localSAS
font.pointSize
:
CallStyle
.
zrtpArea
.
fontSize
font.bold
:
true
color
:
Colors
.
i
}
Text
{
text
:
"
-
"
font.pointSize
:
CallStyle
.
zrtpArea
.
fontSize
color
:
Colors
.
j
}
Text
{
text
:
qsTr
(
"
Your correspondent should say:
"
)
font.pointSize
:
CallStyle
.
zrtpArea
.
fontSize
color
:
Colors
.
j
}
Text
{
text
:
incall
.
call
.
remoteSAS
font.pointSize
:
CallStyle
.
zrtpArea
.
fontSize
font.bold
:
true
color
:
Colors
.
i
}
}
RowLayout
{
anchors.horizontalCenter
:
parent
.
horizontalCenter
spacing
:
CallStyle
.
zrtpArea
.
vu
.
spacing
Layout.fillWidth
:
true
TextButtonA
{
text
:
qsTr
(
'
Deny
'
)
onClicked
:
{
zrtp
.
visible
=
false
incall
.
call
.
verifyAuthenticationToken
(
false
)
}
}
TextButtonB
{
text
:
qsTr
(
'
Accept
'
)
onClicked
:
{
zrtp
.
visible
=
false
incall
.
call
.
verifyAuthenticationToken
(
true
)
}
}
}
}
}
// -------------------------------------------------------------------------
// Action Buttons.
// -------------------------------------------------------------------------
...
...
linphone-desktop/ui/views/App/Styles/Calls/CallStyle.qml
View file @
59010084
...
...
@@ -76,4 +76,13 @@ QtObject {
property
int
relativeY
:
90
}
}
property
QtObject
zrtpArea
:
QtObject
{
property
int
height
:
50
property
int
fontSize
:
12
property
QtObject
vu
:
QtObject
{
property
int
spacing
:
5
}
}
}
linphone
@
19a0bf17
Subproject commit
87ca1adf5ef967bb3876ea0c060cb9135f36718d
Subproject commit
19a0bf173f7060dec5023292239a715ed807e327
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