pull/280/head
Aaron Kaplan 2015-05-27 21:10:33 +02:00
commit d9ae3c19b8
39 changed files with 2502 additions and 486 deletions

View File

@ -12,6 +12,7 @@ Contributions from: (incomplete list, contact us to add your name)
Copyright Christophe Vandeplas
Copyright Belgian Defence
Copyright NATO / NCIRC
Copyright Andras Iklody
This code is licensed under the GNU AFFERO GENERAL PUBLIC LICENSE version 3.

View File

@ -191,7 +191,6 @@ chmod 700 /var/www/MISP/.gnupg
# can't connect to `/var/www/MISP/.gnupg/S.gpg-agent': No such file or directory
gpg --homedir /var/www/MISP/.gnupg --gen-key
chown -R apache:apache /var/www/MISP/.gnupg
# Recommended key type: RSA
# The email address should match the one set in the config.php configuration file
# Make sure that you use the same settings in the MISP Server Settings tool (Described on line 212)

View File

@ -205,7 +205,7 @@ chmod 700 /var/www/MISP/.gnupg
# can't connect to `/var/www/MISP/.gnupg/S.gpg-agent': No such file or directory
gpg --homedir /var/www/MISP/.gnupg --gen-key
chown -R apache:apache /var/www/MISP/.gnupg
# Recommended key type: RSA
# The email address should match the one set in the config.php configuration file
# Make sure that you use the same settings in the MISP Server Settings tool (Described on line 226)

View File

@ -152,6 +152,7 @@ cp -a config.default.php config.php
# require_once dirname(__DIR__) . '/Vendor/autoload.php';
# Important! Change the salt key in /var/www/MISP/app/Config/config.php
# The salt key must be an at least 32 byte long string.
# The admin user account will be generated on the first login, make sure that the salt is changed before you create that user
# If you forget to do this step, and you are still dealing with a fresh installation, just alter the salt,
# delete the user from mysql and log in again using the default admin credentials (admin@admin.test / admin)
@ -165,7 +166,7 @@ mkdir /var/www/MISP/.gnupg
chown www-data:www-data /var/www/MISP/.gnupg
chmod 700 /var/www/MISP/.gnupg
sudo -u www-data gpg --homedir /var/www/MISP/.gnupg --gen-key
# Recommended key type: RSA
# The email address should match the one set in the config.php configuration file
# Make sure that you use the same settings in the MISP Server Settings tool (Described on line 184)

View File

@ -7,7 +7,7 @@ git pull
# 2. Update CakePHP to the latest 2.6 code
cd /var/www/MISP/Lib/cakephp
cd /var/www/MISP/app/Lib/cakephp
git fetch origin
git checkout 2.6

View File

@ -0,0 +1,746 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
x="0px"
y="0px"
viewBox="0 0 620 539.6"
enable-background="new 0 0 620 539.6"
xml:space="preserve"
id="svg2"
inkscape:version="0.48.4 r9939"
width="100%"
height="100%"
sodipodi:docname="misp-database-01.svg"
inkscape:export-filename="/home/adulau/git/circl.lu/web/circl/static/assets/images/misp/misp-database-01.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"><title
id="title3125">MISP Database</title><metadata
id="metadata346"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title>MISP Database</dc:title><cc:license
rdf:resource="http://creativecommons.org/licenses/by-sa/3.0/" /><dc:creator><cc:Agent><dc:title>Alexandre Dulaunoy</dc:title></cc:Agent></dc:creator></cc:Work><cc:License
rdf:about="http://creativecommons.org/licenses/by-sa/3.0/"><cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction" /><cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution" /><cc:requires
rdf:resource="http://creativecommons.org/ns#Notice" /><cc:requires
rdf:resource="http://creativecommons.org/ns#Attribution" /><cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" /><cc:requires
rdf:resource="http://creativecommons.org/ns#ShareAlike" /></cc:License></rdf:RDF></metadata><defs
id="defs344"><inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 269.8 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="620 : 269.8 : 1"
inkscape:persp3d-origin="310 : 179.86667 : 1"
id="perspective5189" /><linearGradient
y2="322.0442"
x2="171.5513"
y1="322.0442"
x1="41.1114"
gradientUnits="userSpaceOnUse"
id="SVGID_1_"><stop
id="stop6"
style="stop-color:#2D4754"
offset="0" /><stop
id="stop8"
style="stop-color:#517F95"
offset="0.897" /></linearGradient><linearGradient
y2="342.361"
x2="171.5513"
y1="342.361"
x1="41.1114"
gradientUnits="userSpaceOnUse"
id="SVGID_2_"><stop
id="stop257"
style="stop-color:#2D4754"
offset="0" /><stop
id="stop259"
style="stop-color:#517F95"
offset="0.897" /></linearGradient><linearGradient
y2="361.8867"
x2="171.5513"
y1="361.8867"
x1="41.1114"
gradientUnits="userSpaceOnUse"
id="SVGID_3_"><stop
id="stop266"
style="stop-color:#2D4754"
offset="0" /><stop
id="stop268"
style="stop-color:#517F95"
offset="0.897" /></linearGradient><linearGradient
y2="381.3294"
x2="171.5513"
y1="381.3294"
x1="41.1114"
gradientUnits="userSpaceOnUse"
id="SVGID_4_"><stop
id="stop275"
style="stop-color:#2D4754"
offset="0" /><stop
id="stop277"
style="stop-color:#517F95"
offset="0.897" /></linearGradient><linearGradient
y2="450.0442"
x2="171.5513"
y1="450.0442"
x1="41.1114"
gradientUnits="userSpaceOnUse"
id="SVGID_5_"><stop
id="stop292"
style="stop-color:#2D4754"
offset="0" /><stop
id="stop294"
style="stop-color:#517F95"
offset="0.897" /></linearGradient><linearGradient
y2="470.361"
x2="171.5513"
y1="470.361"
x1="41.1114"
gradientUnits="userSpaceOnUse"
id="SVGID_6_"><stop
id="stop303"
style="stop-color:#2D4754"
offset="0" /><stop
id="stop305"
style="stop-color:#517F95"
offset="0.897" /></linearGradient><linearGradient
y2="489.8867"
x2="171.5513"
y1="489.8867"
x1="41.1114"
gradientUnits="userSpaceOnUse"
id="SVGID_7_"><stop
id="stop312"
style="stop-color:#2D4754"
offset="0" /><stop
id="stop314"
style="stop-color:#517F95"
offset="0.897" /></linearGradient><linearGradient
y2="509.3294"
x2="171.5513"
y1="509.3294"
x1="41.1114"
gradientUnits="userSpaceOnUse"
id="SVGID_8_"><stop
id="stop321"
style="stop-color:#2D4754"
offset="0" /><stop
id="stop323"
style="stop-color:#517F95"
offset="0.897" /></linearGradient></defs><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1503"
inkscape:window-height="1314"
id="namedview342"
showgrid="false"
inkscape:zoom="1.7582312"
inkscape:cx="308.17494"
inkscape:cy="269.8"
inkscape:window-x="65"
inkscape:window-y="24"
inkscape:window-maximized="0"
inkscape:current-layer="svg2" /><g
transform="matrix(0.48294062,0,0,0.48294062,159.59694,267.84488)"
id="g16-7"><g
id="g18-4"><g
id="g20-9"><g
id="g22-5"><path
style="fill:#df2d38"
inkscape:connector-curvature="0"
id="path24-0"
d="m 330.4,267.7 c 56.6,-12.1 90.5,-70.2 73.1,-125.4 l -109.1,63 36,62.4" /></g></g><path
style="fill:#df2d38"
inkscape:connector-curvature="0"
id="path26-1"
d="M 359,86.9 C 318.4,63.5 268.1,72.3 237.7,105.5 L 347.1,168.7 383,106.5 C 376.3,98.8 368.2,92.2 359,86.9" /><g
id="g28-2"><g
id="g30-8"><path
style="fill:#df2d38"
inkscape:connector-curvature="0"
id="path32-7"
d="m 260.9,256.7 c 8.9,5.2 18.4,8.8 28,10.9 V 141.2 h -72.2 c -14.1,43.2 3.3,91.9 44.2,115.5" /></g></g></g><circle
d="m 391.49999,172 c 0,44.79029 -36.3097,81.1 -81.1,81.1 C 265.6097,253.1 229.3,216.79029 229.3,172 c 0,-44.79029 36.3097,-81.099998 81.09999,-81.099998 44.7903,0 81.1,36.309708 81.1,81.099998 z"
style="fill:#ffffff"
sodipodi:ry="81.099998"
sodipodi:rx="81.099998"
sodipodi:cy="172"
sodipodi:cx="310.39999"
id="circle34-5"
r="81.099998"
cy="172"
cx="310.39999" /><circle
d="m 386.39999,172 c 0,41.97364 -34.02636,76 -76,76 -41.97364,0 -76,-34.02636 -76,-76 0,-41.97364 34.02636,-76 76,-76 41.97364,0 76,34.02636 76,76 z"
style="fill:#456c80"
sodipodi:ry="76"
sodipodi:rx="76"
sodipodi:cy="172"
sodipodi:cx="310.39999"
id="circle36-4"
r="76"
cy="172"
cx="310.39999" /><g
style="opacity:0.2"
id="g38-8"><path
style="fill:#ffffff"
inkscape:connector-curvature="0"
id="path40-9"
d="m 295.7,205.7 88.6,-51.1 c -0.2,-0.7 -0.3,-1.5 -0.5,-2.2 l -91,52.5 24.7,42.8 c 0.8,-0.1 1.6,-0.2 2.3,-0.3 l -24.1,-41.7 z" /><path
style="fill:#ffffff"
inkscape:connector-curvature="0"
id="path42-1"
d="m 372,127.6 c -0.5,-0.6 -0.9,-1.3 -1.4,-1.9 l -23.9,41.5 -88.1,-50.9 c -0.5,0.5 -1.1,1 -1.6,1.6 l 90.5,52.2 24.5,-42.5 z" /><path
style="fill:#ffffff"
inkscape:connector-curvature="0"
id="path44-0"
d="m 241.2,140.2 c -0.3,0.7 -0.7,1.4 -1,2.2 h 47.5 v 102.3 c 0.7,0.2 1.4,0.4 2.2,0.6 V 140.2 h -48.7 z" /></g></g><circle
transform="matrix(0.7377108,0,0,0.7377108,80.089585,94.422275)"
style="fill:#ffffff"
sodipodi:ry="41.200001"
sodipodi:rx="41.200001"
sodipodi:cy="346.20001"
sodipodi:cx="310.70001"
id="circle176-2"
r="41.200001"
cy="346.20001"
cx="310.70001" /><g
id="g16"
transform="matrix(1.433995,0,0,1.433995,-70.969854,-92.111422)"><g
id="g18"><g
id="g20"><g
id="g22"><path
style="fill:#df2d38"
inkscape:connector-curvature="0"
id="path24"
d="m 330.4,267.7 c 56.6,-12.1 90.5,-70.2 73.1,-125.4 l -109.1,63 36,62.4" /></g></g><path
style="fill:#df2d38"
inkscape:connector-curvature="0"
id="path26"
d="M 359,86.9 C 318.4,63.5 268.1,72.3 237.7,105.5 L 347.1,168.7 383,106.5 C 376.3,98.8 368.2,92.2 359,86.9" /><g
id="g28"><g
id="g30"><path
style="fill:#df2d38"
inkscape:connector-curvature="0"
id="path32"
d="m 260.9,256.7 c 8.9,5.2 18.4,8.8 28,10.9 V 141.2 h -72.2 c -14.1,43.2 3.3,91.9 44.2,115.5" /></g></g></g><circle
style="fill:#ffffff"
sodipodi:ry="81.099998"
sodipodi:rx="81.099998"
sodipodi:cy="172"
sodipodi:cx="310.39999"
id="circle34"
r="81.099998"
cy="172"
cx="310.39999"
d="m 391.49999,172 c 0,44.79029 -36.3097,81.1 -81.1,81.1 C 265.6097,253.1 229.3,216.79029 229.3,172 c 0,-44.79029 36.3097,-81.099998 81.09999,-81.099998 44.7903,0 81.1,36.309708 81.1,81.099998 z" /><circle
style="fill:#456c80"
sodipodi:ry="76"
sodipodi:rx="76"
sodipodi:cy="172"
sodipodi:cx="310.39999"
id="circle36"
r="76"
cy="172"
cx="310.39999"
d="m 386.39999,172 c 0,41.97364 -34.02636,76 -76,76 -41.97364,0 -76,-34.02636 -76,-76 0,-41.97364 34.02636,-76 76,-76 41.97364,0 76,34.02636 76,76 z" /><g
style="opacity:0.2"
id="g38"><path
style="fill:#ffffff"
inkscape:connector-curvature="0"
id="path40"
d="m 295.7,205.7 88.6,-51.1 c -0.2,-0.7 -0.3,-1.5 -0.5,-2.2 l -91,52.5 24.7,42.8 c 0.8,-0.1 1.6,-0.2 2.3,-0.3 l -24.1,-41.7 z" /><path
style="fill:#ffffff"
inkscape:connector-curvature="0"
id="path42"
d="m 372,127.6 c -0.5,-0.6 -0.9,-1.3 -1.4,-1.9 l -23.9,41.5 -88.1,-50.9 c -0.5,0.5 -1.1,1 -1.6,1.6 l 90.5,52.2 24.5,-42.5 z" /><path
style="fill:#ffffff"
inkscape:connector-curvature="0"
id="path44"
d="m 241.2,140.2 c -0.3,0.7 -0.7,1.4 -1,2.2 h 47.5 v 102.3 c 0.7,0.2 1.4,0.4 2.2,0.6 V 140.2 h -48.7 z" /></g></g><circle
style="fill:#456c80"
sodipodi:ry="51.599998"
sodipodi:rx="51.599998"
sodipodi:cy="172.7"
sodipodi:cx="528.59998"
id="circle56"
r="51.599998"
cy="172.7"
cx="528.59998"
transform="translate(-406.08995,276.59555)" /><circle
style="fill:#456c80"
sodipodi:ry="40.200001"
sodipodi:rx="40.200001"
sodipodi:cy="477"
sodipodi:cx="309.79999"
id="circle58"
r="40.200001"
cy="477"
cx="309.79999"
transform="translate(-1.0900879e-6,-22)" /><circle
style="fill:none;stroke:#ffffff;stroke-miterlimit:10"
sodipodi:ry="35.900002"
sodipodi:rx="35.900002"
sodipodi:cy="477"
sodipodi:cx="309.79999"
id="circle60"
r="35.900002"
cy="477"
cx="309.79999"
stroke-miterlimit="10"
transform="translate(-1.0900879e-6,-22)" /><g
id="g62"
transform="translate(-406.08995,276.59555)"><path
style="fill:#ffffff"
inkscape:connector-curvature="0"
id="path64"
d="m 551.7,184 h -4.6 c -5.1,0 -9.3,-4.2 -9.3,-9.3 v -3 c 2.1,-2.4 3.5,-5.3 4.4,-8.4 0.1,-0.5 0.6,-0.8 0.9,-1.1 1.8,-1.8 2.1,-4.8 0.8,-6.9 -0.2,-0.3 -0.5,-0.6 -0.5,-1 0,-2.7 0,-5.4 0,-8.2 -0.1,-3.3 -1,-6.7 -3.3,-9.1 -1.9,-2 -4.4,-3.1 -7,-3.6 -3.3,-0.6 -6.8,-0.6 -10.1,0.2 -2.9,0.7 -5.5,2.4 -7.2,4.9 -1.5,2.2 -2.1,4.8 -2.2,7.3 0,2.8 0,5.5 0,8.3 0.1,0.6 -0.4,0.9 -0.6,1.4 -1.3,2.3 -0.7,5.4 1.3,7 0.5,0.4 0.6,1 0.8,1.6 0.9,2.7 2.3,5.3 4.2,7.5 v 3.1 c 0,5.1 -4.2,9.3 -9.3,9.3 h -4.6 c 0,0 -8.4,2.3 -13.9,13.9 v 4.6 c 0,2.6 2.1,4.6 4.6,4.6 0,0 9.5,13.9 32.5,13.9 23,0 32.5,-13.9 32.5,-13.9 2.6,0 4.6,-2.1 4.6,-4.6 v -4.6 c -5.5,-11.6 -14,-13.9 -14,-13.9 z" /></g><text
style="font-size:13.28569412px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Sawasdee;-inkscape-font-specification:Sawasdee Bold"
id="text66"
font-size="16.7142"
x="91.72644"
y="479.52954"
sodipodi:linespacing="125%">API USERS</text>
<circle
style="fill:#456c80"
sodipodi:ry="51.599998"
sodipodi:rx="51.599998"
sodipodi:cy="172.7"
sodipodi:cx="90.599998"
id="circle68"
r="51.599998"
cy="172.7"
cx="90.599998"
transform="translate(30.65063,-31.100055)" /><g
id="g70"
transform="translate(30.65063,-31.100055)"><path
style="fill:#ffffff"
inkscape:connector-curvature="0"
id="path72"
d="m 113.7,184 h -4.6 c -5.1,0 -9.3,-4.2 -9.3,-9.3 v -3 c 2.1,-2.4 3.5,-5.3 4.4,-8.4 0.1,-0.5 0.6,-0.8 0.9,-1.1 1.8,-1.8 2.1,-4.8 0.8,-6.9 -0.2,-0.3 -0.5,-0.6 -0.5,-1 0,-2.7 0,-5.4 0,-8.2 -0.1,-3.3 -1,-6.7 -3.3,-9.1 -1.9,-2 -4.4,-3.1 -7,-3.6 -3.3,-0.6 -6.8,-0.6 -10.1,0.2 -2.9,0.7 -5.5,2.4 -7.2,4.9 -1.5,2.2 -2.1,4.8 -2.2,7.3 0,2.8 0,5.5 0,8.3 0.1,0.6 -0.4,0.9 -0.6,1.4 -1.3,2.3 -0.7,5.4 1.3,7 0.5,0.4 0.6,1 0.8,1.6 0.9,2.7 2.3,5.3 4.2,7.5 v 3.1 c 0,5.1 -4.2,9.3 -9.3,9.3 h -4.6 c 0,0 -8.4,2.3 -13.9,13.9 v 4.6 c 0,2.6 2.1,4.6 4.6,4.6 0,0 9.5,13.9 32.5,13.9 23,0 32.5,-13.9 32.5,-13.9 2.6,0 4.6,-2.1 4.6,-4.6 v -4.6 c -5.5,-11.6 -14,-13.9 -14,-13.9 z" /></g><text
style="font-size:13.28569412px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Sawasdee;-inkscape-font-specification:Sawasdee Bold"
id="text74"
font-size="16.7142"
x="93.879501"
y="172.40268"
sodipodi:linespacing="125%">UI USERS</text>
<g
id="g178"
transform="matrix(0.7377108,0,0,0.7377108,79.276325,94.730995)"
style="fill:#28170b"><path
style="fill:#28170b"
inkscape:connector-curvature="0"
id="path180"
d="m 310.7,345.1 c -9,0 -16.1,-3.2 -16.1,-7.3 v -4.6 c 0,-0.7 0.2,-1.3 0.6,-2 l 0.7,-1.3 0.7,1.3 c 1.3,2.2 6.5,4.5 14,4.5 7.5,0 12.7,-2.3 14,-4.5 l 0.7,-1.3 0.7,1.3 c 0.4,0.7 0.6,1.3 0.6,2 v 4.6 c 0.2,4 -6.9,7.3 -15.9,7.3 z m -14.3,-11.7 v 4.3 c 0,2.7 5.9,5.6 14.3,5.6 8.4,0 14.3,-3 14.3,-5.6 v -4.3 c -2.6,2.4 -8.1,4 -14.3,4 -6.3,-0.1 -11.7,-1.6 -14.3,-4 z" /><path
style="fill:#28170b"
inkscape:connector-curvature="0"
id="path182"
d="m 310.7,354.2 c -9,0 -16.1,-3.2 -16.1,-7.3 v -4.6 c 0,-0.7 0.2,-1.3 0.6,-2 l 0.7,-1.3 0.7,1.3 c 1.3,2.2 6.5,4.5 14,4.5 7.5,0 12.7,-2.3 14,-4.5 l 0.7,-1.3 0.7,1.3 c 0.4,0.7 0.6,1.3 0.6,2 v 4.6 c 0.2,4.1 -6.9,7.3 -15.9,7.3 z m -14.3,-11.6 v 4.4 c 0,2.7 5.9,5.6 14.3,5.6 8.4,0 14.3,-3 14.3,-5.6 v -4.4 c -2.6,2.4 -8.1,4 -14.3,4 -6.3,-0.1 -11.7,-1.6 -14.3,-4 z" /><path
style="fill:#28170b"
inkscape:connector-curvature="0"
id="path184"
d="m 310.7,335.7 c -9,0 -16.1,-3.2 -16.1,-7.3 v -4.6 c 0,-0.6 0.2,-1.3 0.5,-1.9 l 1.3,-2.4 0.3,2.7 c 0.2,1.6 5.2,4 13.9,4 8.7,0 13.8,-2.3 13.9,-4 l 0.3,-2.7 1.3,2.4 c 0.3,0.6 0.5,1.3 0.5,1.9 v 4.6 c 0.2,4.1 -6.9,7.3 -15.9,7.3 z m -14.3,-11.1 v 3.9 c 0,2.6 5.9,5.6 14.3,5.6 8.4,0 14.3,-3 14.3,-5.6 v -3.9 c -2.6,2.2 -8.6,3.3 -14.3,3.3 -5.7,0 -11.8,-1.2 -14.3,-3.3 z" /><path
style="fill:#28170b"
inkscape:connector-curvature="0"
id="path186"
d="m 310.7,326.4 c -7.6,0 -15.7,-2 -15.7,-5.8 0,-3.8 8.1,-5.8 15.7,-5.8 7.6,0 15.7,2 15.7,5.8 0,3.8 -8.1,5.8 -15.7,5.8 z m 0,-9.8 c -8.6,0 -14,2.3 -14,4 0,1.7 5.3,4 14,4 8.7,0 14,-2.4 14,-4 0,-1.6 -5.4,-4 -14,-4 z" /></g><text
style="font-size:9.80099964px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Sawasdee;-inkscape-font-specification:Sawasdee Bold"
id="text188"
font-size="12"
x="289.99179"
y="366.6835"
sodipodi:linespacing="125%">Database</text>
<text
style="font-size:13.28569412px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;font-family:Sawasdee;-inkscape-font-specification:Sawasdee Bold"
id="text190"
font-size="16.7142"
x="299.83774"
y="477.7005"
sodipodi:linespacing="125%">API</text>
<g
id="g192"
transform="translate(-186.92133,-32.237565)"
style="fill:#241c1c"><path
style="fill:#241c1c"
inkscape:connector-curvature="0"
id="path194"
d="m 297.9,461.3 c 0.1,0.5 0.3,1 0.6,1.4 l -0.7,0.9 c -0.2,0.3 -0.2,0.7 0.1,1 l 1.2,1.2 c 0.3,0.3 0.7,0.3 1,0.1 l 0.9,-0.7 c 0.5,0.3 1,0.5 1.5,0.6 l 0.1,1.2 c 0,0.4 0.4,0.7 0.7,0.7 h 1.8 c 0.4,0 0.7,-0.3 0.7,-0.7 l 0.1,-1.1 c 0.6,-0.1 1.1,-0.4 1.6,-0.6 l 0.9,0.7 c 0.3,0.2 0.7,0.2 1,-0.1 l 1.2,-1.2 c 0.3,-0.3 0.3,-0.7 0.1,-1 l -0.7,-0.9 c 0.3,-0.5 0.5,-1 0.6,-1.5 l 1,-0.1 c 0.4,0 0.7,-0.4 0.7,-0.7 v -1.8 c 0,-0.4 -0.3,-0.7 -0.7,-0.7 l -1,-0.1 c -0.1,-0.5 -0.4,-1.1 -0.6,-1.5 l 0.6,-0.8 c 0.2,-0.3 0.2,-0.7 -0.1,-1 l -1.2,-1.2 c -0.3,-0.3 -0.7,-0.3 -1,-0.1 l -0.8,0.6 c -0.5,-0.3 -1,-0.5 -1.6,-0.7 l -0.1,-1 c 0,-0.4 -0.4,-0.7 -0.7,-0.7 h -1.8 c -0.4,0 -0.7,0.3 -0.7,0.7 l -0.1,1 c -0.6,0.2 -1.1,0.4 -1.7,0.7 l -0.8,-0.6 c -0.3,-0.2 -0.7,-0.2 -1,0.1 l -1.2,1.2 c -0.3,0.3 -0.3,0.7 -0.1,1 l 0.7,0.9 c -0.3,0.5 -0.5,1 -0.6,1.5 l -1.1,0.1 c -0.4,0 -0.7,0.4 -0.7,0.7 v 1.8 c 0,0.4 0.3,0.7 0.7,0.7 l 1.2,0 z m 6.3,-4.8 c 1.6,0 2.9,1.3 2.9,2.9 0,1.6 -1.3,2.9 -2.9,2.9 -1.6,0 -2.9,-1.3 -2.9,-2.9 0,-1.6 1.3,-2.9 2.9,-2.9 z" /><path
style="fill:#241c1c"
inkscape:connector-curvature="0"
id="path196"
d="m 321.6,461.7 -0.9,-0.8 c -0.3,-0.2 -0.7,-0.2 -1,0 l -0.5,0.5 c -0.4,-0.2 -0.9,-0.4 -1.4,-0.4 l -0.1,-0.7 c -0.1,-0.4 -0.4,-0.6 -0.8,-0.6 l -1.2,0.1 c -0.4,0 -0.7,0.3 -0.7,0.7 l 0,0.7 c -0.5,0.2 -0.9,0.4 -1.3,0.7 l -0.6,-0.4 c -0.3,-0.2 -0.7,-0.1 -1,0.1 l -0.8,0.9 c -0.2,0.3 -0.2,0.7 0,1 l 0.5,0.6 c -0.2,0.4 -0.3,0.9 -0.4,1.3 l -0.8,0.2 c -0.4,0.1 -0.6,0.4 -0.6,0.8 l 0.1,1.2 c 0,0.4 0.3,0.7 0.7,0.7 l 0.8,0 c 0.1,0.4 0.3,0.8 0.6,1.1 l -0.5,0.7 c -0.2,0.3 -0.1,0.7 0.1,1 l 0.9,0.8 c 0.3,0.2 0.7,0.2 1,0 l 0.6,-0.6 c 0.4,0.2 0.8,0.3 1.2,0.4 l 0.2,0.8 c 0.1,0.4 0.4,0.6 0.8,0.6 l 1.2,-0.1 c 0.4,0 0.7,-0.3 0.7,-0.7 l 0,-0.8 c 0.4,-0.2 0.9,-0.4 1.2,-0.6 l 0.7,0.4 c 0.3,0.2 0.7,0.1 1,-0.1 l 0.8,-0.9 c 0.2,-0.3 0.2,-0.7 0,-1 l -0.5,-0.6 c 0.2,-0.4 0.3,-0.9 0.4,-1.3 l 0.7,-0.1 c 0.4,-0.1 0.6,-0.4 0.6,-0.8 l -0.1,-1.2 c 0,-0.4 -0.3,-0.7 -0.7,-0.7 l -0.7,0 c -0.2,-0.4 -0.4,-0.8 -0.6,-1.2 l 0.4,-0.6 c 0.3,-0.4 0.2,-0.9 0,-1.1 z m -4.6,7 c -1.3,0.1 -2.5,-0.9 -2.6,-2.2 -0.1,-1.3 0.9,-2.5 2.2,-2.6 1.3,-0.1 2.5,0.9 2.6,2.2 0.1,1.3 -0.9,2.5 -2.2,2.6 z" /><path
style="fill:#241c1c"
inkscape:connector-curvature="0"
id="path198"
d="m 302.1,471.9 c -0.4,0 -0.7,0.3 -0.7,0.7 l 0,0.7 c 0,0.4 0.3,0.7 0.6,0.7 l 0.5,0.1 c 0.1,0.3 0.2,0.6 0.4,0.9 l -0.4,0.4 c -0.2,0.3 -0.2,0.7 0,1 l 0.5,0.5 c 0.3,0.3 0.7,0.3 1,0.1 l 0.4,-0.3 c 0.3,0.2 0.6,0.3 1,0.4 l 0.1,0.6 c 0,0.4 0.3,0.7 0.7,0.7 l 0.7,0 c 0.4,0 0.7,-0.3 0.7,-0.6 l 0.1,-0.5 c 0.4,-0.1 0.7,-0.2 1.1,-0.4 l 0.4,0.3 c 0.3,0.2 0.7,0.2 1,0 l 0.5,-0.5 c 0.3,-0.3 0.3,-0.7 0.1,-1 l -0.3,-0.4 c 0.2,-0.3 0.3,-0.7 0.4,-1 l 0.5,0 c 0.4,0 0.7,-0.3 0.7,-0.7 l 0,-0.7 c 0,-0.4 -0.3,-0.7 -0.6,-0.7 l -0.5,-0.1 c -0.1,-0.4 -0.2,-0.7 -0.4,-1 l 0.3,-0.4 c 0.2,-0.3 0.2,-0.7 0,-1 l -0.5,-0.5 c -0.3,-0.3 -0.7,-0.3 -1,-0.1 l -0.4,0.3 c -0.3,-0.2 -0.7,-0.4 -1.1,-0.5 l 0,-0.5 c 0,-0.4 -0.3,-0.7 -0.7,-0.7 l -0.7,0 c -0.4,0 -0.7,0.3 -0.7,0.6 l -0.1,0.5 c -0.4,0.1 -0.8,0.3 -1.1,0.5 l -0.4,-0.3 c -0.3,-0.2 -0.7,-0.2 -1,0 l -0.5,0.5 c -0.3,0.3 -0.3,0.7 -0.1,1 l 0.3,0.4 c -0.2,0.3 -0.3,0.7 -0.4,1 l -0.4,0 z m 4.8,-0.8 c 1.1,0 1.9,0.9 1.9,2 0,1.1 -0.9,1.9 -2,1.9 -1.1,0 -1.9,-0.9 -1.9,-2 0.1,-1.1 0.9,-1.9 2,-1.9 z" /></g><g
id="g5181"
transform="translate(-252.58858,-182.0011)"><circle
transform="matrix(0.6622787,0,0,0.6622787,257.25078,173.21214)"
cx="487"
cy="335.29999"
r="40.200001"
id="circle12"
sodipodi:cx="487"
sodipodi:cy="335.29999"
sodipodi:rx="40.200001"
sodipodi:ry="40.200001"
style="fill:#456c80"
d="m 527.2,335.29999 c 0,22.20185 -17.99815,40.2 -40.2,40.2 -22.20185,0 -40.2,-17.99815 -40.2,-40.2 0,-22.20185 17.99815,-40.2 40.2,-40.2 22.20185,0 40.2,17.99815 40.2,40.2 z" /><circle
transform="matrix(0.6622787,0,0,0.6622787,257.25078,173.21214)"
stroke-miterlimit="10"
cx="487"
cy="335.29999"
r="35.900002"
id="circle204"
sodipodi:cx="487"
sodipodi:cy="335.29999"
sodipodi:rx="35.900002"
sodipodi:ry="35.900002"
style="fill:none;stroke:#ffffff;stroke-miterlimit:10"
d="m 522.9,335.29999 c 0,19.82702 -16.07298,35.9 -35.9,35.9 -19.82702,0 -35.9,-16.07298 -35.9,-35.9 0,-19.82703 16.07298,-35.9 35.9,-35.9 19.82702,0 35.9,16.07297 35.9,35.9 z" /><g
transform="matrix(0.8723196,0,0,0.8723196,154.00869,113.31128)"
id="g232"><text
transform="translate(459.5688,355.7476)"
font-size="16.7142"
id="text234"
style="font-size:16.71419907px;fill:#ffffff;font-family:Ubuntu-Bold" />
<g
id="g236"><path
d="m 495.1,325.6 c -1.5,0 -2.9,0.7 -3.8,1.9 l -8.2,-4.2 c 0.1,-0.4 0.2,-0.8 0.2,-1.3 0,-0.5 -0.1,-0.9 -0.2,-1.4 l 8.2,-4.2 c 0.9,1.2 2.3,1.9 3.9,1.9 2.7,0 4.9,-2.2 4.9,-4.9 0,-2.7 -2.2,-4.9 -4.9,-4.9 -2.7,0 -4.9,2.2 -4.9,4.9 0,0.4 0.1,0.9 0.2,1.3 l -8.2,4.2 c -0.9,-1.1 -2.3,-1.9 -3.8,-1.9 -2.7,0 -4.9,2.2 -4.9,4.9 0,2.7 2.2,4.9 4.9,4.9 1.6,0 3,-0.8 3.9,-1.9 l 8.2,4.2 c -0.1,0.4 -0.2,0.9 -0.2,1.4 0,2.7 2.2,4.9 4.9,4.9 2.7,0 4.9,-2.2 4.9,-4.9 -0.2,-2.7 -2.4,-4.9 -5.1,-4.9 z"
id="path238"
inkscape:connector-curvature="0"
style="fill:#ffffff" /></g></g></g><g
id="g5171"
transform="translate(-285.00752,-156.40719)"><circle
transform="matrix(0.6622787,0,0,0.6622787,210.04424,97.567934)"
cx="559.20001"
cy="335.29999"
r="40.200001"
id="circle200"
sodipodi:cx="559.20001"
sodipodi:cy="335.29999"
sodipodi:rx="40.200001"
sodipodi:ry="40.200001"
style="fill:#456c80"
d="m 599.40001,335.29999 c 0,22.20185 -17.99815,40.2 -40.2,40.2 -22.20185,0 -40.2,-17.99815 -40.2,-40.2 0,-22.20185 17.99815,-40.2 40.2,-40.2 22.20185,0 40.2,17.99815 40.2,40.2 z" /><circle
transform="matrix(0.6622787,0,0,0.6622787,210.04424,97.274196)"
stroke-miterlimit="10"
cx="559.20001"
cy="335.29999"
r="35.900002"
id="circle202"
sodipodi:cx="559.20001"
sodipodi:cy="335.29999"
sodipodi:rx="35.900002"
sodipodi:ry="35.900002"
style="fill:none;stroke:#ffffff;stroke-miterlimit:10"
d="m 595.10001,335.29999 c 0,19.82702 -16.07297,35.9 -35.9,35.9 -19.82702,0 -35.9,-16.07298 -35.9,-35.9 0,-19.82703 16.07298,-35.9 35.9,-35.9 19.82703,0 35.9,16.07297 35.9,35.9 z" /><g
transform="matrix(0.91339425,0,0,0.91339425,69.468797,14.90405)"
id="g240"><g
transform="translate(0.56875344,13.081329)"
id="g244"><g
id="g246"><path
d="m 569.8,328.3 -5.1,-5.1 c -0.8,1.2 -1.8,2.2 -3,3 l 5.1,5.1 c 0.8,0.8 2.2,0.8 3,0 0.8,-0.9 0.8,-2.2 0,-3 z"
id="path248"
inkscape:connector-curvature="0"
style="fill:#ffffff" /><path
d="m 564.8,317.8 c 0,-4.6 -3.8,-8.4 -8.4,-8.4 -4.6,0 -8.4,3.8 -8.4,8.4 0,4.6 3.8,8.4 8.4,8.4 4.7,0 8.4,-3.7 8.4,-8.4 z m -8.4,6.3 c -3.5,0 -6.3,-2.8 -6.3,-6.3 0,-3.5 2.8,-6.3 6.3,-6.3 3.5,0 6.3,2.8 6.3,6.3 0,3.5 -2.8,6.3 -6.3,6.3 z"
id="path250"
inkscape:connector-curvature="0"
style="fill:#ffffff" /><path
d="m 551.5,317.8 h 1.4 c 0,-1.9 1.6,-3.5 3.5,-3.5 v -1.4 c -2.7,0 -4.9,2.2 -4.9,4.9 z"
id="path252"
inkscape:connector-curvature="0"
style="fill:#ffffff" /></g></g></g></g><g
id="Layer_2" /><circle
style="fill:#ffffff"
sodipodi:ry="64.900002"
sodipodi:rx="64.900002"
sodipodi:cy="171.5"
sodipodi:cx="310.5"
id="circle46"
r="64.900002"
cy="171.5"
cx="310.5"
transform="matrix(0.94918452,0,0,0.95901479,75.54985,-51.187427)" /><g
id="g5113"
transform="matrix(1.1493281,0,0,1.1493281,-140.61097,-34.423291)"><text
sodipodi:linespacing="125%"
style="font-size:40px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Sawasdee;-inkscape-font-specification:Sawasdee Bold"
y="128.30263"
x="398.4176"
id="text48"><tspan
y="128.30263"
x="398.4176"
id="tspan3533"
sodipodi:role="line">MISP</tspan></text>
<line
stroke-miterlimit="10"
x1="393.08832"
y1="131.18111"
x2="493.08832"
y2="131.18111"
id="line54"
style="fill:none;stroke:#456c80;stroke-width:1;stroke-miterlimit:10" /><text
sodipodi:linespacing="125%"
style="font-size:16px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Sawasdee;-inkscape-font-specification:Sawasdee Bold"
y="144.8582"
x="392.10303"
id="text48-4"><tspan
y="144.8582"
x="392.10303"
id="tspan3533-7"
sodipodi:role="line">Threat Sharing</tspan></text>
</g><g
id="g5251"
transform="translate(340.68331,12.512576)"><rect
y="380.53043"
x="79.625465"
height="127.96952"
width="165.65707"
id="rect4544"
style="fill:#456c80;fill-opacity:1;stroke-width:5;stroke-miterlimit:10;stroke-dasharray:none" /><text
sodipodi:linespacing="125%"
y="402.62067"
x="85.891724"
font-size="12"
id="text309"
style="font-size:12.00000095px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;stroke-width:5;stroke-miterlimit:10;stroke-dasharray:none;font-family:Sawasdee;-inkscape-font-specification:Sawasdee Bold"><tspan
y="402.62067"
x="85.891724"
id="tspan4564"
sodipodi:role="line">MISP XML and JSON</tspan><tspan
y="417.62067"
x="85.891724"
id="tspan4566"
sodipodi:role="line">OpenIOC</tspan><tspan
y="432.62067"
x="85.891724"
id="tspan4568"
sodipodi:role="line">STIX XML and JSON (export)</tspan><tspan
y="447.62067"
x="85.891724"
id="tspan4570"
sodipodi:role="line">Suricata export</tspan><tspan
y="462.62067"
x="85.891724"
id="tspan4572"
sodipodi:role="line">Snort export</tspan><tspan
y="477.62067"
x="85.891724"
id="tspan4574"
sodipodi:role="line">CSV export</tspan><tspan
y="492.62067"
x="85.891724"
id="tspan4576"
sodipodi:role="line">GFI import</tspan><tspan
y="507.62067"
x="85.891724"
id="tspan4578"
sodipodi:role="line" /><tspan
y="522.62067"
x="85.891724"
id="tspan4580"
sodipodi:role="line" /><tspan
y="537.62067"
x="85.891724"
id="tspan4582"
sodipodi:role="line" /></text>
</g><polygon
style="fill:#2d4754"
id="polygon331-6"
points="29,465.6 36.9,470.2 29,474.8 "
transform="matrix(1.6250433,0,0,1.6250433,149.43773,-636.63482)" /><polygon
style="fill:#2d4754"
id="polygon331-1-1"
points="36.9,470.2 29,474.8 29,465.6 "
transform="matrix(-1.6250433,0,0,1.6250433,256.52808,-611.66042)" /><polygon
style="fill:#2d4754"
id="polygon331-6-3"
points="29,474.8 29,465.6 36.9,470.2 "
transform="matrix(1.6250433,0,0,1.6250433,329.22587,-324.38918)" /><polygon
style="fill:#2d4754"
id="polygon331-1-1-0"
points="29,465.6 36.9,470.2 29,474.8 "
transform="matrix(-1.6250433,0,0,1.6250433,436.31622,-299.41478)" /><flowRoot
xml:space="preserve"
id="flowRoot5055"
style="fill:black;stroke:none;stroke-opacity:1;stroke-width:1px;stroke-linejoin:miter;stroke-linecap:butt;fill-opacity:1;font-family:Sans;font-style:normal;font-weight:normal;font-size:40px;line-height:125%;letter-spacing:0px;word-spacing:0px"><flowRegion
id="flowRegion5057"><rect
id="rect5059"
width="1.1375068"
height="57.444096"
x="429.97757"
y="213.7043" /></flowRegion><flowPara
id="flowPara5061" /></flowRoot><g
id="g192-1"
transform="translate(1.4581189,-19.581663)"
style="fill:#ffffff;fill-opacity:1"><path
style="fill:#ffffff;fill-opacity:1"
inkscape:connector-curvature="0"
id="path194-8"
d="m 297.9,461.3 c 0.1,0.5 0.3,1 0.6,1.4 l -0.7,0.9 c -0.2,0.3 -0.2,0.7 0.1,1 l 1.2,1.2 c 0.3,0.3 0.7,0.3 1,0.1 l 0.9,-0.7 c 0.5,0.3 1,0.5 1.5,0.6 l 0.1,1.2 c 0,0.4 0.4,0.7 0.7,0.7 h 1.8 c 0.4,0 0.7,-0.3 0.7,-0.7 l 0.1,-1.1 c 0.6,-0.1 1.1,-0.4 1.6,-0.6 l 0.9,0.7 c 0.3,0.2 0.7,0.2 1,-0.1 l 1.2,-1.2 c 0.3,-0.3 0.3,-0.7 0.1,-1 l -0.7,-0.9 c 0.3,-0.5 0.5,-1 0.6,-1.5 l 1,-0.1 c 0.4,0 0.7,-0.4 0.7,-0.7 v -1.8 c 0,-0.4 -0.3,-0.7 -0.7,-0.7 l -1,-0.1 c -0.1,-0.5 -0.4,-1.1 -0.6,-1.5 l 0.6,-0.8 c 0.2,-0.3 0.2,-0.7 -0.1,-1 l -1.2,-1.2 c -0.3,-0.3 -0.7,-0.3 -1,-0.1 l -0.8,0.6 c -0.5,-0.3 -1,-0.5 -1.6,-0.7 l -0.1,-1 c 0,-0.4 -0.4,-0.7 -0.7,-0.7 h -1.8 c -0.4,0 -0.7,0.3 -0.7,0.7 l -0.1,1 c -0.6,0.2 -1.1,0.4 -1.7,0.7 l -0.8,-0.6 c -0.3,-0.2 -0.7,-0.2 -1,0.1 l -1.2,1.2 c -0.3,0.3 -0.3,0.7 -0.1,1 l 0.7,0.9 c -0.3,0.5 -0.5,1 -0.6,1.5 l -1.1,0.1 c -0.4,0 -0.7,0.4 -0.7,0.7 v 1.8 c 0,0.4 0.3,0.7 0.7,0.7 l 1.2,0 z m 6.3,-4.8 c 1.6,0 2.9,1.3 2.9,2.9 0,1.6 -1.3,2.9 -2.9,2.9 -1.6,0 -2.9,-1.3 -2.9,-2.9 0,-1.6 1.3,-2.9 2.9,-2.9 z" /><path
style="fill:#ffffff;fill-opacity:1"
inkscape:connector-curvature="0"
id="path196-1"
d="m 321.6,461.7 -0.9,-0.8 c -0.3,-0.2 -0.7,-0.2 -1,0 l -0.5,0.5 c -0.4,-0.2 -0.9,-0.4 -1.4,-0.4 l -0.1,-0.7 c -0.1,-0.4 -0.4,-0.6 -0.8,-0.6 l -1.2,0.1 c -0.4,0 -0.7,0.3 -0.7,0.7 l 0,0.7 c -0.5,0.2 -0.9,0.4 -1.3,0.7 l -0.6,-0.4 c -0.3,-0.2 -0.7,-0.1 -1,0.1 l -0.8,0.9 c -0.2,0.3 -0.2,0.7 0,1 l 0.5,0.6 c -0.2,0.4 -0.3,0.9 -0.4,1.3 l -0.8,0.2 c -0.4,0.1 -0.6,0.4 -0.6,0.8 l 0.1,1.2 c 0,0.4 0.3,0.7 0.7,0.7 l 0.8,0 c 0.1,0.4 0.3,0.8 0.6,1.1 l -0.5,0.7 c -0.2,0.3 -0.1,0.7 0.1,1 l 0.9,0.8 c 0.3,0.2 0.7,0.2 1,0 l 0.6,-0.6 c 0.4,0.2 0.8,0.3 1.2,0.4 l 0.2,0.8 c 0.1,0.4 0.4,0.6 0.8,0.6 l 1.2,-0.1 c 0.4,0 0.7,-0.3 0.7,-0.7 l 0,-0.8 c 0.4,-0.2 0.9,-0.4 1.2,-0.6 l 0.7,0.4 c 0.3,0.2 0.7,0.1 1,-0.1 l 0.8,-0.9 c 0.2,-0.3 0.2,-0.7 0,-1 l -0.5,-0.6 c 0.2,-0.4 0.3,-0.9 0.4,-1.3 l 0.7,-0.1 c 0.4,-0.1 0.6,-0.4 0.6,-0.8 l -0.1,-1.2 c 0,-0.4 -0.3,-0.7 -0.7,-0.7 l -0.7,0 c -0.2,-0.4 -0.4,-0.8 -0.6,-1.2 l 0.4,-0.6 c 0.3,-0.4 0.2,-0.9 0,-1.1 z m -4.6,7 c -1.3,0.1 -2.5,-0.9 -2.6,-2.2 -0.1,-1.3 0.9,-2.5 2.2,-2.6 1.3,-0.1 2.5,0.9 2.6,2.2 0.1,1.3 -0.9,2.5 -2.2,2.6 z" /><path
style="fill:#ffffff;fill-opacity:1"
inkscape:connector-curvature="0"
id="path198-2"
d="m 302.1,471.9 c -0.4,0 -0.7,0.3 -0.7,0.7 l 0,0.7 c 0,0.4 0.3,0.7 0.6,0.7 l 0.5,0.1 c 0.1,0.3 0.2,0.6 0.4,0.9 l -0.4,0.4 c -0.2,0.3 -0.2,0.7 0,1 l 0.5,0.5 c 0.3,0.3 0.7,0.3 1,0.1 l 0.4,-0.3 c 0.3,0.2 0.6,0.3 1,0.4 l 0.1,0.6 c 0,0.4 0.3,0.7 0.7,0.7 l 0.7,0 c 0.4,0 0.7,-0.3 0.7,-0.6 l 0.1,-0.5 c 0.4,-0.1 0.7,-0.2 1.1,-0.4 l 0.4,0.3 c 0.3,0.2 0.7,0.2 1,0 l 0.5,-0.5 c 0.3,-0.3 0.3,-0.7 0.1,-1 l -0.3,-0.4 c 0.2,-0.3 0.3,-0.7 0.4,-1 l 0.5,0 c 0.4,0 0.7,-0.3 0.7,-0.7 l 0,-0.7 c 0,-0.4 -0.3,-0.7 -0.6,-0.7 l -0.5,-0.1 c -0.1,-0.4 -0.2,-0.7 -0.4,-1 l 0.3,-0.4 c 0.2,-0.3 0.2,-0.7 0,-1 l -0.5,-0.5 c -0.3,-0.3 -0.7,-0.3 -1,-0.1 l -0.4,0.3 c -0.3,-0.2 -0.7,-0.4 -1.1,-0.5 l 0,-0.5 c 0,-0.4 -0.3,-0.7 -0.7,-0.7 l -0.7,0 c -0.4,0 -0.7,0.3 -0.7,0.6 l -0.1,0.5 c -0.4,0.1 -0.8,0.3 -1.1,0.5 l -0.4,-0.3 c -0.3,-0.2 -0.7,-0.2 -1,0 l -0.5,0.5 c -0.3,0.3 -0.3,0.7 -0.1,1 l 0.3,0.4 c -0.2,0.3 -0.3,0.7 -0.4,1 l -0.4,0 z m 4.8,-0.8 c 1.1,0 1.9,0.9 1.9,2 0,1.1 -0.9,1.9 -2,1.9 -1.1,0 -1.9,-0.9 -1.9,-2 0.1,-1.1 0.9,-1.9 2,-1.9 z" /></g><circle
style="fill:#ffffff"
sodipodi:ry="64.900002"
sodipodi:rx="64.900002"
sodipodi:cy="171.5"
sodipodi:cx="310.5"
id="circle46-4"
r="64.900002"
cy="171.5"
cx="310.5"
transform="matrix(0.70755265,0,0,0.71488046,183.77339,82.775869)" /><circle
style="fill:#ffffff"
sodipodi:ry="64.900002"
sodipodi:rx="64.900002"
sodipodi:cy="171.5"
sodipodi:cx="310.5"
id="circle46-2"
r="64.900002"
cy="171.5"
cx="310.5"
transform="matrix(0.55419079,0,0,0.5599303,227.69536,111.23738)" /><circle
style="fill:none;stroke:#456c80;stroke-miterlimit:10"
sodipodi:ry="40.200001"
sodipodi:rx="40.200001"
sodipodi:cy="459.89999"
sodipodi:cx="537.5"
id="circle14"
r="40.200001"
cy="459.89999"
cx="537.5"
stroke-miterlimit="10"
transform="matrix(0.6622787,0,0,0.6622787,48.45622,-99.220752)" /><circle
style="fill:#456c80"
sodipodi:ry="24.200001"
sodipodi:rx="24.200001"
sodipodi:cy="429.20001"
sodipodi:cx="559"
id="circle206"
r="24.200001"
cy="429.20001"
cx="559"
transform="matrix(0.6622787,0,0,0.6622787,48.45622,-99.220752)" /><circle
style="fill:none;stroke:#ffffff;stroke-miterlimit:10"
sodipodi:ry="21.6"
sodipodi:rx="21.6"
sodipodi:cy="429.20001"
sodipodi:cx="559"
id="circle208"
r="21.6"
cy="429.20001"
cx="559"
stroke-miterlimit="10"
transform="matrix(0.6622787,0,0,0.6622787,48.45622,-99.220752)" /><circle
style="fill:#456c80"
sodipodi:ry="24.200001"
sodipodi:rx="24.200001"
sodipodi:cy="493.20001"
sodipodi:cx="559.09998"
id="circle210"
r="24.200001"
cy="493.20001"
cx="559.09998"
transform="matrix(0.6622787,0,0,0.6622787,48.45622,-99.220752)" /><circle
style="fill:none;stroke:#ffffff;stroke-miterlimit:10"
sodipodi:ry="21.6"
sodipodi:rx="21.6"
sodipodi:cy="493.20001"
sodipodi:cx="559.09998"
id="circle212"
r="21.6"
cy="493.20001"
cx="559.09998"
stroke-miterlimit="10"
transform="matrix(0.6622787,0,0,0.6622787,48.45622,-99.220752)" /><circle
style="fill:#456c80"
sodipodi:ry="24.200001"
sodipodi:rx="24.200001"
sodipodi:cy="461.29999"
sodipodi:cx="500"
id="circle214"
r="24.200001"
cy="461.29999"
cx="500"
transform="matrix(0.6622787,0,0,0.6622787,48.45622,-99.220752)" /><circle
style="fill:none;stroke:#ffffff;stroke-miterlimit:10"
sodipodi:ry="21.6"
sodipodi:rx="21.6"
sodipodi:cy="461.29999"
sodipodi:cx="500"
id="circle216"
r="21.6"
cy="461.29999"
cx="500"
stroke-miterlimit="10"
transform="matrix(0.6622787,0,0,0.6622787,48.45622,-99.220752)" /><text
style="font-size:8.79883194px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;font-family:Sawasdee;-inkscape-font-specification:Sawasdee Bold"
id="text218"
font-size="16.7142"
x="414.30298"
y="188.2943"
sodipodi:linespacing="125%">IP</text>
<text
id="text220"
x="406.69278"
y="227.00908"
style="font-size:7.94734526px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Sawasdee;-inkscape-font-specification:Sawasdee Bold"
sodipodi:linespacing="125%"><tspan
style="font-size:7.94734526px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;font-family:Sawasdee;-inkscape-font-specification:Sawasdee Bold"
id="tspan222"
font-size="10"
y="227.00908"
x="406.69278">EVENT</tspan><tspan
style="font-size:7.94734526px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;font-family:Sawasdee;-inkscape-font-specification:Sawasdee Bold"
id="tspan224"
font-size="10"
y="234.29414"
x="415.43484">B</tspan></text>
<text
id="text226"
x="367.92834"
y="206.92221"
style="font-size:8px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Sawasdee;-inkscape-font-specification:Sawasdee Bold"
sodipodi:linespacing="125%"><tspan
style="font-size:8px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;font-family:Sawasdee;-inkscape-font-specification:Sawasdee Bold"
id="tspan228"
font-size="10"
y="206.92221"
x="367.92834">EVENT</tspan><tspan
style="font-size:8px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;font-family:Sawasdee;-inkscape-font-specification:Sawasdee Bold"
id="tspan230"
font-size="10"
y="215.29514"
x="377.74747">A</tspan></text>
<polygon
style="fill:#2d4754"
id="polygon331-6-2"
points="29,465.6 36.9,470.2 29,474.8 "
transform="matrix(1.6250433,0,0,1.6250433,155.75608,-323.43306)" /><polygon
style="fill:#2d4754"
id="polygon331-1-1-1"
points="36.9,470.2 29,474.8 29,465.6 "
transform="matrix(-1.6250433,0,0,1.6250433,262.84642,-298.45866)" /></svg>

After

Width:  |  Height:  |  Size: 38 KiB

View File

@ -0,0 +1,747 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 18.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
x="0px"
y="0px"
viewBox="0 0 620 445.7"
enable-background="new 0 0 620 445.7"
xml:space="preserve"
id="svg2"
inkscape:version="0.48.4 r9939"
width="100%"
height="100%"
sodipodi:docname="misp-flows.svg"
inkscape:export-filename="/home/adulau/git/circl.lu/web/circl/static/assets/images/misp/misp-flows.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"><title
id="title3146">MISP Community overview</title><metadata
id="metadata264"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title>MISP Community overview</dc:title><dc:creator><cc:Agent><dc:title>Alexandre Dulaunoy</dc:title></cc:Agent></dc:creator><cc:license
rdf:resource="http://creativecommons.org/licenses/by-sa/3.0/" /></cc:Work><cc:License
rdf:about="http://creativecommons.org/licenses/by-sa/3.0/"><cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction" /><cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution" /><cc:requires
rdf:resource="http://creativecommons.org/ns#Notice" /><cc:requires
rdf:resource="http://creativecommons.org/ns#Attribution" /><cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" /><cc:requires
rdf:resource="http://creativecommons.org/ns#ShareAlike" /></cc:License></rdf:RDF></metadata><defs
id="defs262" /><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="2495"
inkscape:window-height="1416"
id="namedview260"
showgrid="false"
inkscape:zoom="2.0149341"
inkscape:cx="291.40203"
inkscape:cy="281.43763"
inkscape:window-x="65"
inkscape:window-y="24"
inkscape:window-maximized="1"
inkscape:current-layer="svg2" /><g
id="g5"><g
id="g7"><g
id="g9"><g
id="g11"><path
style="fill:#df2d38"
inkscape:connector-curvature="0"
id="path13"
d="M 133.4,205.7 C 190,193.6 223.9,135.5 206.5,80.3 l -109.1,63 36,62.4" /></g></g><path
style="fill:#df2d38"
inkscape:connector-curvature="0"
id="path15"
d="M 162,24.9 C 121.4,1.4 71.1,10.3 40.7,43.4 L 150.1,106.6 186,44.4 C 179.3,36.8 171.2,30.2 162,24.9" /><g
id="g17"><g
id="g19"><path
style="fill:#df2d38"
inkscape:connector-curvature="0"
id="path21"
d="m 63.9,194.7 c 8.9,5.2 18.4,8.8 28,10.9 V 79.2 H 19.8 C 5.6,122.4 23,171.1 63.9,194.7" /></g></g></g><circle
style="fill:#ffffff"
sodipodi:ry="81.099998"
sodipodi:rx="81.099998"
sodipodi:cy="110"
sodipodi:cx="113.4"
id="circle23"
r="81.099998"
cy="110"
cx="113.4" /><circle
style="fill:#456c80"
sodipodi:ry="76"
sodipodi:rx="76"
sodipodi:cy="110"
sodipodi:cx="113.4"
id="circle25"
r="76"
cy="110"
cx="113.4" /><g
style="opacity:0.2"
id="g27"><path
style="fill:#ffffff"
inkscape:connector-curvature="0"
id="path29"
d="m 98.7,143.7 88.6,-51.1 c -0.2,-0.7 -0.3,-1.5 -0.5,-2.2 l -91,52.5 24.7,42.8 c 0.8,-0.1 1.6,-0.2 2.3,-0.3 L 98.7,143.7 z" /><path
style="fill:#ffffff"
inkscape:connector-curvature="0"
id="path31"
d="m 175,65.6 c -0.5,-0.6 -0.9,-1.3 -1.4,-1.9 L 149.7,105.2 61.5,54.3 c -0.5,0.5 -1.1,1 -1.6,1.6 l 90.5,52.2 24.6,-42.5 z" /><path
style="fill:#ffffff"
inkscape:connector-curvature="0"
id="path33"
d="m 44.2,78.2 c -0.3,0.7 -0.7,1.4 -1,2.2 h 47.5 v 102.3 c 0.7,0.2 1.4,0.4 2.2,0.6 V 78.2 H 44.2 z" /></g></g><circle
style="fill:#ffffff"
sodipodi:ry="64.900002"
sodipodi:rx="64.900002"
sodipodi:cy="109.5"
sodipodi:cx="113.5"
id="circle35"
r="64.900002"
cy="109.5"
cx="113.5" /><text
id="text37"
x="91.910202"
y="88.209"><tspan
style="font-size:16.71419907px;font-family:HelveticaNeueLTStd-Bd"
id="tspan39"
font-size="16.7142"
y="88.209"
x="91.910202">MISP</tspan><tspan
style="font-size:16.71419907px;font-family:HelveticaLTStd-Light"
id="tspan41"
font-size="16.7142"
y="111.909"
x="60.910198">Private Sector</tspan></text>
<line
style="fill:none;stroke:#456c80;stroke-miterlimit:10"
id="line43"
y2="94.5"
x2="163"
y1="94.5"
x1="63"
stroke-miterlimit="10" /><g
id="g45"><g
id="g47"><g
id="g49"><g
id="g51"><path
style="fill:#df2d38"
inkscape:connector-curvature="0"
id="path53"
d="m 505.2,187.6 c 45.9,-9.8 73.3,-56.9 59.2,-101.6 l -88.4,51 29.2,50.6" /></g></g><path
style="fill:#df2d38"
inkscape:connector-curvature="0"
id="path55"
d="M 528.4,41 C 495.5,22 454.7,29.2 430.1,56.1 l 88.7,51.2 29.1,-50.4 C 542.5,50.7 535.9,45.3 528.4,41" /><g
id="g57"><g
id="g59"><path
style="fill:#df2d38"
inkscape:connector-curvature="0"
id="path61"
d="m 449,178.6 c 7.3,4.2 14.9,7.1 22.7,8.8 V 85.1 h -58.5 c -11.6,35 2.6,74.4 35.8,93.5" /></g></g></g><circle
style="fill:#ffffff"
sodipodi:ry="65.699997"
sodipodi:rx="65.699997"
sodipodi:cy="110"
sodipodi:cx="489"
id="circle63"
r="65.699997"
cy="110"
cx="489" /><circle
style="fill:#456c80"
sodipodi:ry="61.599998"
sodipodi:rx="61.599998"
sodipodi:cy="110"
sodipodi:cx="489"
id="circle65"
r="61.599998"
cy="110"
cx="489" /><g
style="opacity:0.2"
id="g67"><path
style="fill:#ffffff"
inkscape:connector-curvature="0"
id="path69"
d="m 477.1,137.3 71.8,-41.4 c -0.1,-0.6 -0.3,-1.2 -0.4,-1.8 l -73.7,42.6 20,34.7 c 0.6,-0.1 1.3,-0.1 1.9,-0.2 l -19.6,-33.9 z" /><path
style="fill:#ffffff"
inkscape:connector-curvature="0"
id="path71"
d="m 539,74 c -0.4,-0.5 -0.8,-1 -1.1,-1.5 L 518.5,106.1 447,64.9 c -0.4,0.4 -0.9,0.8 -1.3,1.3 L 519.1,108.5 539,74 z" /><path
style="fill:#ffffff"
inkscape:connector-curvature="0"
id="path73"
d="m 433,84.2 c -0.3,0.6 -0.5,1.2 -0.8,1.7 h 38.5 v 82.9 c 0.6,0.2 1.2,0.3 1.7,0.5 V 84.2 H 433 z" /></g></g><circle
style="fill:#ffffff"
sodipodi:ry="52.599998"
sodipodi:rx="52.599998"
sodipodi:cy="109.7"
sodipodi:cx="488.70001"
id="circle75"
r="52.599998"
cy="109.7"
cx="488.70001" /><text
style="font-size:16.71419907px;font-family:HelveticaNeueLTStd-Bd"
id="text77"
font-size="16.7142"
x="463.6524"
y="99.422401">MISP</text>
<line
style="fill:none;stroke:#456c80;stroke-miterlimit:10"
id="line79"
y2="105.5"
x2="524"
y1="105.5"
x1="446"
stroke-miterlimit="10" /><text
id="text81"
x="464.95801"
y="122.7139"><tspan
style="font-size:13.92850018px;font-family:HelveticaLTStd-Light"
id="tspan83"
font-size="13.9285"
y="122.7139"
x="464.95801">CERT </tspan><tspan
style="font-size:13.92850018px;font-family:HelveticaLTStd-Light"
id="tspan85"
font-size="13.9285"
y="135.2139"
x="449.45801">Community</tspan></text>
<text
style="font-size:16.71419907px;font-family:HelveticaNeueLTStd-Bd"
id="text87"
font-size="16.7142"
x="287.64941"
y="102.6407">CIRCL</text>
<text
style="font-size:16.71419907px;font-family:HelveticaNeueLTStd-Bd"
id="text89"
font-size="16.7142"
x="13.667"
y="268.22079">Legend:</text>
<text
style="font-size:13.92850018px;font-family:HelveticaLTStd-Light"
id="text91"
font-size="13.9285"
x="252.3428"
y="125.9317">API Clearing House</text>
<text
style="font-size:13.92850018px;font-family:HelveticaLTStd-Light"
id="text93"
font-size="13.9285"
x="53.3946"
y="307.64069">Operated by CIRCL</text>
<text
style="font-size:16.71419907px;font-family:HelveticaNeueLTStd-Bd"
id="text95"
font-size="16.7142"
x="498.6524"
y="224.35941">MISP</text>
<text
style="font-size:13.92850018px;font-family:HelveticaLTStd-Light"
id="text97"
font-size="13.9285"
x="498.52539"
y="240.6866">Synchronisation</text>
<g
id="g99"><g
id="g101"><line
style="fill:none;stroke:#456c80;stroke-miterlimit:10"
id="line103"
y2="109.5"
x2="387"
y1="109.5"
x1="234"
stroke-miterlimit="10" /><g
id="g105"><polygon
style="fill:#456c80"
id="polygon107"
points="236,102.9 236,116.7 224,109.8 " /></g><g
id="g109"><polygon
style="fill:#456c80"
id="polygon111"
points="385,102.9 385,116.7 397,109.8 " /></g></g></g><g
id="g113"><g
id="g115"><line
style="fill:none;stroke:#456c80;stroke-miterlimit:10"
id="line117"
y2="204"
x2="485.5"
y1="245"
x1="485.5"
stroke-miterlimit="10" /><g
id="g119"><polygon
style="fill:#456c80"
id="polygon121"
points="478.9,243 492.8,243 485.8,255 " /></g><g
id="g123"><polygon
style="fill:#456c80"
id="polygon125"
points="478.9,206 492.8,206 485.8,194 " /></g></g></g><rect
style="fill:none"
id="rect127"
height="30.1"
width="115.2"
y="122.1"
x="55.400002" /><text
id="text129"
x="80.440498"
y="128.14799"><tspan
style="font-size:8.35709953px;fill:#6d6e70;font-family:HelveticaLTStd-Light"
id="tspan131"
font-size="8.3571"
y="128.14799"
x="80.440498">Private national &amp; </tspan><tspan
style="font-size:8.35709953px;fill:#6d6e70;font-family:HelveticaLTStd-Light"
id="tspan133"
font-size="8.3571"
y="137.948"
x="64.640503">International organization, </tspan><tspan
style="font-size:8.35709953px;fill:#6d6e70;font-family:HelveticaLTStd-Light"
id="tspan135"
font-size="8.3571"
y="147.64799"
x="82.740501">Private CERTs...</tspan></text>
<rect
style="fill:none"
id="rect137"
height="31.799999"
width="115.2"
y="130.5"
x="431.10001" /><g
id="g147"><g
id="g149"><g
id="g151"><path
style="fill:#c8c9ca"
inkscape:connector-curvature="0"
id="path153"
d="m 505.2,418.8 c 45.9,-9.8 73.3,-56.9 59.2,-101.6 l -88.4,51 29.2,50.6" /></g></g><path
style="fill:#c8c9ca"
inkscape:connector-curvature="0"
id="path155"
d="m 528.4,272.2 c -32.9,-19 -73.7,-11.8 -98.3,15.1 l 88.7,51.2 29.1,-50.4 c -5.4,-6.2 -12,-11.5 -19.5,-15.9" /><g
id="g157"><g
id="g159"><path
style="fill:#c8c9ca"
inkscape:connector-curvature="0"
id="path161"
d="m 449,409.9 c 7.3,4.2 14.9,7.1 22.7,8.8 V 316.3 h -58.5 c -11.6,35 2.6,74.4 35.8,93.6" /></g></g></g><circle
style="fill:#ffffff"
sodipodi:ry="65.699997"
sodipodi:rx="65.699997"
sodipodi:cy="341.20001"
sodipodi:cx="489"
id="circle163"
r="65.699997"
cy="341.20001"
cx="489" /><circle
style="fill:#456c80"
sodipodi:ry="61.599998"
sodipodi:rx="61.599998"
sodipodi:cy="341.20001"
sodipodi:cx="489"
id="circle165"
r="61.599998"
cy="341.20001"
cx="489" /><g
style="opacity:0.2"
id="g167"><path
style="fill:#ffffff"
inkscape:connector-curvature="0"
id="path169"
d="m 477.1,368.6 71.8,-41.4 c -0.1,-0.6 -0.3,-1.2 -0.4,-1.8 l -73.7,42.6 20,34.7 c 0.6,-0.1 1.3,-0.1 1.9,-0.2 l -19.6,-33.9 z" /><path
style="fill:#ffffff"
inkscape:connector-curvature="0"
id="path171"
d="m 539,305.2 c -0.4,-0.5 -0.8,-1 -1.1,-1.5 L 518.5,337.3 447,296.1 c -0.4,0.4 -0.9,0.8 -1.3,1.3 l 73.4,42.3 19.9,-34.5 z" /><path
style="fill:#ffffff"
inkscape:connector-curvature="0"
id="path173"
d="m 433,315.4 c -0.3,0.6 -0.5,1.2 -0.8,1.7 h 38.5 V 400 c 0.6,0.2 1.2,0.3 1.7,0.5 V 315.3 H 433 z" /></g><circle
style="fill:#ffffff"
sodipodi:ry="52.599998"
sodipodi:rx="52.599998"
sodipodi:cy="340.89999"
sodipodi:cx="488.70001"
id="circle175"
r="52.599998"
cy="340.89999"
cx="488.70001" /><text
style="font-size:16.71419907px;font-family:HelveticaNeueLTStd-Bd"
id="text177"
font-size="16.7142"
x="467.6524"
y="316.63681">MISP</text>
<line
style="fill:none;stroke:#456c80;stroke-miterlimit:10"
id="line179"
y2="322.5"
x2="528"
y1="322.5"
x1="450"
stroke-miterlimit="10" /><text
id="text181"
x="469.7305"
y="339.9278"><tspan
style="font-size:13.92850018px;font-family:HelveticaLTStd-Light"
id="tspan183"
font-size="13.9285"
y="339.9278"
x="469.7305">NATO</tspan><tspan
style="font-size:13.92850018px;font-family:HelveticaLTStd-Light"
id="tspan185"
font-size="13.9285"
y="353.82779"
x="467.03049">NCIRC</tspan></text>
<rect
style="fill:none"
id="rect187"
height="31.799999"
width="115.2"
y="361.70001"
x="431.10001" /><text
id="text189"
x="460.60449"
y="367.71881"><tspan
style="font-size:8.35709953px;fill:#6d6e70;font-family:HelveticaLTStd-Light"
id="tspan191"
font-size="8.3571"
y="367.71881"
x="460.60449">NATO Member</tspan><tspan
style="font-size:8.35709953px;fill:#6d6e70;font-family:HelveticaLTStd-Light"
id="tspan193"
font-size="8.3571"
y="377.5188"
x="470.8045">Countries</tspan></text>
<g
id="g195"><g
id="g197"><g
id="g199"><g
id="g201"><path
style="fill:#df2d38"
inkscape:connector-curvature="0"
id="path203"
d="m 34,317.5 c 8.9,-1.9 14.2,-11 11.5,-19.6 l -17.1,9.9 5.6,9.7" /></g></g><path
style="fill:#df2d38"
inkscape:connector-curvature="0"
id="path205"
d="m 38.5,289.1 c -6.4,-3.7 -14.2,-2.3 -19,2.9 l 17.1,9.9 5.6,-9.7 C 41.2,291 40,290 38.5,289.1" /><g
id="g207"><g
id="g209"><path
style="fill:#df2d38"
inkscape:connector-curvature="0"
id="path211"
d="m 23.2,315.7 c 1.4,0.8 2.9,1.4 4.4,1.7 V 297.6 H 16.2 c -2.2,6.8 0.6,14.4 7,18.1" /></g></g></g><circle
style="fill:#ffffff"
sodipodi:ry="12.7"
sodipodi:rx="12.7"
sodipodi:cy="302.5"
sodipodi:cx="30.9"
id="circle213"
r="12.7"
cy="302.5"
cx="30.9"
d="m 43.599999,302.5 c 0,7.01402 -5.685983,12.7 -12.699999,12.7 -7.014017,0 -12.7,-5.68598 -12.7,-12.7 0,-7.01402 5.685983,-12.7 12.7,-12.7 7.014016,0 12.699999,5.68598 12.699999,12.7 z" /><circle
style="fill:#456c80"
sodipodi:ry="11.9"
sodipodi:rx="11.9"
sodipodi:cy="302.5"
sodipodi:cx="30.9"
id="circle215"
r="11.9"
cy="302.5"
cx="30.9"
d="m 42.799999,302.5 c 0,6.57219 -5.327811,11.9 -11.899999,11.9 -6.572189,0 -11.9,-5.32781 -11.9,-11.9 0,-6.57219 5.327811,-11.9 11.9,-11.9 6.572188,0 11.899999,5.32781 11.899999,11.9 z" /><g
style="opacity:0.2"
id="g217"><path
style="fill:#ffffff"
inkscape:connector-curvature="0"
id="path219"
d="m 28.6,307.8 13.9,-8 c 0,-0.1 -0.1,-0.2 -0.1,-0.3 l -14.3,8.2 3.9,6.7 c 0.1,0 0.2,0 0.4,0 l -3.8,-6.6 z" /><path
style="fill:#ffffff"
inkscape:connector-curvature="0"
id="path221"
d="m 40.6,295.5 c -0.1,-0.1 -0.1,-0.2 -0.2,-0.3 l -3.8,6.5 -13.8,-8 c -0.1,0.1 -0.2,0.2 -0.3,0.2 l 14.2,8.2 3.9,-6.6 z" /><path
style="fill:#ffffff"
inkscape:connector-curvature="0"
id="path223"
d="m 20.1,297.5 c -0.1,0.1 -0.1,0.2 -0.2,0.3 h 7.4 v 16 c 0.1,0 0.2,0.1 0.3,0.1 v -16.5 h -7.5 z" /></g></g><circle
style="fill:#ffffff"
sodipodi:ry="10.2"
sodipodi:rx="10.2"
sodipodi:cy="302.39999"
sodipodi:cx="30.9"
id="circle225"
r="10.2"
cy="302.39999"
cx="30.9" /><text
style="font-size:13.92850018px;font-family:HelveticaLTStd-Light"
id="text227"
font-size="13.9285"
x="53.3946"
y="344.77249">Operated by NATO/NCIRC</text>
<g
id="g229"><g
id="g231"><g
id="g233"><path
style="fill:#c8c9ca"
inkscape:connector-curvature="0"
id="path235"
d="m 34,353.5 c 8.9,-1.9 14.2,-11 11.5,-19.6 l -17.1,9.9 5.6,9.7" /></g></g><path
style="fill:#c8c9ca"
inkscape:connector-curvature="0"
id="path237"
d="m 38.5,325.1 c -6.4,-3.7 -14.2,-2.3 -19,2.9 l 17.1,9.9 5.6,-9.7 C 41.2,327 40,326 38.5,325.1" /><g
id="g239"><g
id="g241"><path
style="fill:#c8c9ca"
inkscape:connector-curvature="0"
id="path243"
d="m 23.2,351.8 c 1.4,0.8 2.9,1.4 4.4,1.7 V 333.7 H 16.2 c -2.2,6.7 0.6,14.4 7,18.1" /></g></g></g><circle
style="fill:#ffffff"
sodipodi:ry="12.7"
sodipodi:rx="12.7"
sodipodi:cy="338.5"
sodipodi:cx="30.9"
id="circle245"
r="12.7"
cy="338.5"
cx="30.9" /><circle
style="fill:#456c80"
sodipodi:ry="11.9"
sodipodi:rx="11.9"
sodipodi:cy="338.5"
sodipodi:cx="30.9"
id="circle247"
r="11.9"
cy="338.5"
cx="30.9" /><g
style="opacity:0.2"
id="g249"><path
style="fill:#ffffff"
inkscape:connector-curvature="0"
id="path251"
d="m 28.6,343.8 13.9,-8 c 0,-0.1 -0.1,-0.2 -0.1,-0.3 l -14.3,8.2 3.9,6.7 c 0.1,0 0.2,0 0.4,0 l -3.8,-6.6 z" /><path
style="fill:#ffffff"
inkscape:connector-curvature="0"
id="path253"
d="m 40.6,331.5 c -0.1,-0.1 -0.1,-0.2 -0.2,-0.3 l -3.8,6.5 -13.8,-8 c -0.1,0.1 -0.2,0.2 -0.3,0.2 l 14.2,8.2 3.9,-6.6 z" /><path
style="fill:#ffffff"
inkscape:connector-curvature="0"
id="path255"
d="m 20.1,333.5 c -0.1,0.1 -0.1,0.2 -0.2,0.3 h 7.4 v 16 c 0.1,0 0.2,0.1 0.3,0.1 v -16.5 h -7.5 z" /></g><circle
style="fill:#ffffff"
sodipodi:ry="10.2"
sodipodi:rx="10.2"
sodipodi:cy="338.39999"
sodipodi:cx="30.9"
id="circle257"
r="10.2"
cy="338.39999"
cx="30.9" /><g
id="Layer_2" /><g
id="g7-7"
transform="matrix(0.39313323,0,0,0.39313323,153.37584,182.6294)"
style="fill:#ffd42a"><g
id="g9-8"
style="fill:#ffd42a"><g
id="g11-9"
style="fill:#ffd42a"><path
d="M 133.4,205.7 C 190,193.6 223.9,135.5 206.5,80.3 l -109.1,63 36,62.4"
id="path13-2"
inkscape:connector-curvature="0"
style="fill:#ffd42a" /></g></g><path
d="M 162,24.9 C 121.4,1.4 71.1,10.3 40.7,43.4 L 150.1,106.6 186,44.4 C 179.3,36.8 171.2,30.2 162,24.9"
id="path15-5"
inkscape:connector-curvature="0"
style="fill:#ffd42a" /><g
id="g17-4"
style="fill:#ffd42a"><g
id="g19-6"
style="fill:#ffd42a"><path
d="m 63.9,194.7 c 8.9,5.2 18.4,8.8 28,10.9 V 79.2 H 19.8 C 5.6,122.4 23,171.1 63.9,194.7"
id="path21-6"
inkscape:connector-curvature="0"
style="fill:#ffd42a" /></g></g></g><circle
cx="113.4"
cy="110"
r="81.099998"
id="circle23-9"
sodipodi:cx="113.4"
sodipodi:cy="110"
sodipodi:rx="81.099998"
sodipodi:ry="81.099998"
style="fill:#ffffff"
d="m 194.5,110 c 0,44.79029 -36.30971,81.1 -81.1,81.1 -44.790291,0 -81.099997,-36.30971 -81.099997,-81.1 0,-44.790292 36.309706,-81.099998 81.099997,-81.099998 44.79029,0 81.1,36.309706 81.1,81.099998 z"
transform="matrix(0.39313323,0,0,0.39313323,153.37584,182.6294)" /><circle
cx="113.4"
cy="110"
r="76"
id="circle25-9"
sodipodi:cx="113.4"
sodipodi:cy="110"
sodipodi:rx="76"
sodipodi:ry="76"
style="fill:#456c80"
d="m 189.4,110 c 0,41.97364 -34.02636,76 -76,76 -41.973639,0 -75.999998,-34.02636 -75.999998,-76 0,-41.973641 34.026359,-76 75.999998,-76 41.97364,0 76,34.026359 76,76 z"
transform="matrix(0.39313323,0,0,0.39313323,153.37584,182.6294)" /><g
id="g27-4"
style="opacity:0.2"
transform="matrix(0.39313323,0,0,0.39313323,153.37584,182.6294)"><path
d="m 98.7,143.7 88.6,-51.1 c -0.2,-0.7 -0.3,-1.5 -0.5,-2.2 l -91,52.5 24.7,42.8 c 0.8,-0.1 1.6,-0.2 2.3,-0.3 L 98.7,143.7 z"
id="path29-7"
inkscape:connector-curvature="0"
style="fill:#ffffff" /><path
d="m 175,65.6 c -0.5,-0.6 -0.9,-1.3 -1.4,-1.9 L 149.7,105.2 61.5,54.3 c -0.5,0.5 -1.1,1 -1.6,1.6 l 90.5,52.2 24.6,-42.5 z"
id="path31-5"
inkscape:connector-curvature="0"
style="fill:#ffffff" /><path
d="m 44.2,78.2 c -0.3,0.7 -0.7,1.4 -1,2.2 h 47.5 v 102.3 c 0.7,0.2 1.4,0.4 2.2,0.6 V 78.2 H 44.2 z"
id="path33-2"
inkscape:connector-curvature="0"
style="fill:#ffffff" /></g><circle
transform="matrix(0.39313323,0,0,0.39313323,153.37584,182.6294)"
style="fill:#ffffff"
sodipodi:ry="64.900002"
sodipodi:rx="64.900002"
sodipodi:cy="109.5"
sodipodi:cx="113.5"
id="circle35-4"
r="64.900002"
cy="109.5"
cx="113.5" /><text
id="text37-8"
x="189.50879"
y="221.3073"
style="font-size:6px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Sans;-inkscape-font-specification:Sans"
sodipodi:linespacing="125%"><tspan
style="font-size:6px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Sans;-inkscape-font-specification:Sans"
id="tspan39-3"
font-size="16.7142"
y="221.3073"
x="189.50879">MISP</tspan></text>
<line
style="fill:none;stroke:#456c80;stroke-width:0.39313322;stroke-miterlimit:10"
id="line43-9"
y2="223.7805"
x2="217.45656"
y1="223.7805"
x1="178.14323"
stroke-miterlimit="10" /><rect
style="fill:none"
id="rect127-1"
height="11.83331"
width="45.288948"
y="234.63098"
x="175.15541" /><text
id="text37-8-7"
x="174.05786"
y="230.74472"
style="font-size:6px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Sans;-inkscape-font-specification:Sans"
sodipodi:linespacing="125%"><tspan
style="font-size:6px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Sans;-inkscape-font-specification:Sans"
id="tspan39-3-0"
font-size="16.7142"
y="230.74472"
x="174.05786">Private Instance</tspan></text>
<text
style="font-size:13.92850018px;font-family:HelveticaLTStd-Light"
id="text93-3"
font-size="13.9285"
x="53.367645"
y="381.59952">Operated by other organizations</text>
<g
id="g197-1"
transform="translate(-0.0269478,73.958832)"
style="fill:#ffd42a"><g
id="g199-1"
style="fill:#ffd42a"><g
id="g201-8"
style="fill:#ffd42a"><path
d="m 34,317.5 c 8.9,-1.9 14.2,-11 11.5,-19.6 l -17.1,9.9 5.6,9.7"
id="path203-2"
inkscape:connector-curvature="0"
style="fill:#ffd42a" /></g></g><path
d="m 38.5,289.1 c -6.4,-3.7 -14.2,-2.3 -19,2.9 l 17.1,9.9 5.6,-9.7 C 41.2,291 40,290 38.5,289.1"
id="path205-2"
inkscape:connector-curvature="0"
style="fill:#ffd42a" /><g
id="g207-4"
style="fill:#ffd42a"><g
id="g209-9"
style="fill:#ffd42a"><path
d="m 23.2,315.7 c 1.4,0.8 2.9,1.4 4.4,1.7 V 297.6 H 16.2 c -2.2,6.8 0.6,14.4 7,18.1"
id="path211-7"
inkscape:connector-curvature="0"
style="fill:#ffd42a" /></g></g></g><circle
cx="30.9"
cy="302.5"
r="12.7"
id="circle213-8"
sodipodi:cx="30.9"
sodipodi:cy="302.5"
sodipodi:rx="12.7"
sodipodi:ry="12.7"
style="fill:#ffffff"
d="m 43.599999,302.5 c 0,7.01402 -5.685983,12.7 -12.699999,12.7 -7.014017,0 -12.7,-5.68598 -12.7,-12.7 0,-7.01402 5.685983,-12.7 12.7,-12.7 7.014016,0 12.699999,5.68598 12.699999,12.7 z"
transform="translate(-0.0269478,73.958832)" /><circle
cx="30.9"
cy="302.5"
r="11.9"
id="circle215-3"
sodipodi:cx="30.9"
sodipodi:cy="302.5"
sodipodi:rx="11.9"
sodipodi:ry="11.9"
style="fill:#456c80"
d="m 42.799999,302.5 c 0,6.57219 -5.327811,11.9 -11.899999,11.9 -6.572189,0 -11.9,-5.32781 -11.9,-11.9 0,-6.57219 5.327811,-11.9 11.9,-11.9 6.572188,0 11.899999,5.32781 11.899999,11.9 z"
transform="translate(-0.0269478,73.958832)" /><g
id="g217-8"
style="opacity:0.2"
transform="translate(-0.0269478,73.958832)"><path
d="m 28.6,307.8 13.9,-8 c 0,-0.1 -0.1,-0.2 -0.1,-0.3 l -14.3,8.2 3.9,6.7 c 0.1,0 0.2,0 0.4,0 l -3.8,-6.6 z"
id="path219-2"
inkscape:connector-curvature="0"
style="fill:#ffffff" /><path
d="m 40.6,295.5 c -0.1,-0.1 -0.1,-0.2 -0.2,-0.3 l -3.8,6.5 -13.8,-8 c -0.1,0.1 -0.2,0.2 -0.3,0.2 l 14.2,8.2 3.9,-6.6 z"
id="path221-6"
inkscape:connector-curvature="0"
style="fill:#ffffff" /><path
d="m 20.1,297.5 c -0.1,0.1 -0.1,0.2 -0.2,0.3 h 7.4 v 16 c 0.1,0 0.2,0.1 0.3,0.1 v -16.5 h -7.5 z"
id="path223-9"
inkscape:connector-curvature="0"
style="fill:#ffffff" /></g><circle
transform="translate(-0.0269478,73.958832)"
style="fill:#ffffff"
sodipodi:ry="10.2"
sodipodi:rx="10.2"
sodipodi:cy="302.39999"
sodipodi:cx="30.9"
id="circle225-5"
r="10.2"
cy="302.39999"
cx="30.9" /><flowRoot
xml:space="preserve"
id="flowRoot3671"
style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
transform="translate(0,-6.1035156e-6)"><flowRegion
id="flowRegion3673"><rect
id="rect3675"
width="169.7326"
height="133.99942"
x="94.792183"
y="147.42722" /></flowRegion><flowPara
id="flowPara3677" /></flowRoot></svg>

After

Width:  |  Height:  |  Size: 27 KiB

View File

@ -26,39 +26,10 @@ The Red October malware for example gives a similar view:
Some people might think about CIF (Collective Intelligence Framework) and CRITs (Collaborative Research Into Threats), however those tools are different. Each one has its strenghts and weaknesses, but in the end MISP will rule the world of course.
Changelog
---------
v2.3 brings important improvements in features, performance and usability:
- STIX export
- Easier editing of large data sets, thanks to AJAX
- Impressive performance improvements in load time (and memory usage)
- Templating system: create templates for your organisation for easier data entry, and optionally share the templates with other organisations on your MISP instance
- Free-text import tool: just paste a list of indicators and let MISP figure out what it is
- Attribute merge tool: update the list of all attributes of the same type by pasting a new list of values
- Diagnostic and configuration tool
- Improved synchronisation
- API improvements
- New Filtering for events / users with bookmarks
v2.2 brings some minor improvements and fixes
v2.1 implements important changes in the database format:
- A complete redesign of the UI
- Added a lot more import/exports formats
- Serious code cleanup
Roadmap
-------
v2.4
- Sharing groups : more control over sharability of data
- Modular import / export: make it easier to add more import/export plugins
v3.0+
- Reworking the MISP data model (phase 1): Move away from the current attribute model and go to a hierarchical object model that allows composite objects (for example a file described by hashes, filename, filesize, etc. being one object). Compatibility with STIX and OpenIOC, allowing us to import data in those formats
- Reworking the MISP data model (phase 2): Build extra structures on top of the current event / attribute structure, such as campaigns, threat actors, TTPs, and so on.
- Integration with other tools: Wide range of possibilities. Import from other sandboxes, directly import from feeds in popular formats. Automate sandboxing procedure (upload sample to your sandbox, automatically create an event based on the result, etc).
- Automatic enrichment: Automatically gather additional information on the data that you are entering. Do look-ups based on hashes, IP addresses, domain and host-names.
Website / Support
------------------
Checkout the [website](http://www.misp-project.org) for more information about MISP like [features](http://www.misp-project.org/#features), [roadmap](http://www.misp-project.org/#roadmap), <small>(commercial)</small> [support](http://www.misp-project.org/#support), ... : http://misp-project.org
Documentation
@ -78,6 +49,6 @@ There are 2 branches:
License
-------
This software is licensed under GNU Affero General Public License version 3
This software is licensed under [GNU Affero General Public License version 3](http://www.gnu.org/licenses/agpl-3.0.html)
Copyright (c) 2012, 2013 Christophe Vandeplas, Belgian Defence, NATO / NCIRC.

View File

@ -1 +1 @@
{"major":2, "minor":3, "hotfix":62}
{"major":2, "minor":3, "hotfix":69}

View File

@ -108,6 +108,12 @@ CakePlugin::load('Assets'); // having Logable
CakePlugin::load('SysLogLogable');
CakePlugin::load('UrlCache');
/**
* Uncomment the following line to enable client SSL certificate authentication.
* It's also necessary to configure the plugin for more information, please read app/Plugin/CertAuth/reame.md
*/
// CakePlugin::load('CertAuth');
/**
* You can attach event listeners to the request lifecyle as Dispatcher Filter . By Default CakePHP bundles two filters:
*

View File

@ -6,6 +6,7 @@ $config = array (
'level' => 'medium',
'salt' => 'Rooraenietu8Eeyo<Qu2eeNfterd-dd+',
'cipherSeed' => '',
//'auth'=>array('CertAuth.Certificate'), // additional authentication methods
),
'MISP' =>
array (
@ -34,6 +35,7 @@ $config = array (
'email' => '',
'homedir' => '',
'password' => '',
'bodyonlyencrypted' => false,
),
'Proxy' =>
array (
@ -48,4 +50,33 @@ $config = array (
'amount' => 5,
'expire' => 300,
),
// Uncomment the following to enable client SSL certificate authentication
/*
'CertAuth' =>
array(
'ca' => array( 'FIRST.Org' ), // allowed CAs
'caId' => 'O', // which attribute will be used to verify the CA
'userModel' => 'User', // name of the User class to check if user exists
'userModelKey' => 'nids_sid', // User field that will be used for querying
'map' => array( // maps client certificate attributes to User properties
'O' => 'org',
'emailAddress'=>'email',
),
'syncUser' => true, // should the User be synchronized with an external REST API
'userDefaults'=> array( // default user attributes, only used when creating new users
'role_id' => 4,
),
'restApi' => array( // API parameters
'url' => 'https://example.com/data/users', // URL to query
'headers' => array(), // additional headers, used for authentication
'param' => array( 'email' => 'email'), // query parameters to add to the URL, mapped to USer properties
'map' => array( // maps REST result to the User properties
'uid' => 'nids_sid',
'team' => 'org',
'email' => 'email',
'pgp_public'=> 'gpgkey',
),
),
),
*/
);

View File

@ -5,7 +5,7 @@ App::uses('File', 'Utility');
require_once 'AppShell.php';
class EventShell extends AppShell
{
public $uses = array('Event', 'Attribute', 'Job', 'User', 'Task', 'Whitelist');
public $uses = array('Event', 'Post', 'Attribute', 'Job', 'User', 'Task', 'Whitelist');
public function doPublish() {
$id = $this->args[0];
@ -299,6 +299,22 @@ class EventShell extends AppShell
$this->Job->saveField('progress', '100');
if ($result != true) $this->Job->saveField('message', 'Job done.');
}
public function postsemail() {
$user_id = $this->args[0];
$post_id = $this->args[1];
$event_id = $this->args[2];
$title = $this->args[3];
$message = $this->args[4];
$processId = $this->args[5];
$this->Job->id = $processId;
$user = $this->User->read(null, $user_id);
$eventId = $this->args[2];
$result = $this->Post->sendPostsEmail($user_id, $post_id, $event_id, $title, $message);
$job['Job']['progress'] = 100;
$job['Job']['message'] = 'Emails sent.';
$this->Job->save($job);
}
public function enqueueCaching() {
$timestamp = $this->args[0];

View File

@ -11,15 +11,10 @@ class PasswordShell extends AppShell {
public function main() {
// get the users that need their password hashed
$results = $this->User->findByEmail($this->args[0]);
//$this->out(print_r($results, true));
App::import('Component','Auth');
$this->Auth = new AuthComponent(new ComponentCollection());
$count = count($results);
$results = $this->User->find('first', array('conditions' => array('email' => $this->args[0])));
$results['User']['password'] = $this->args[1];
$results['User']['confirm_password'] = $this->args[1];
$results['User']['change_pw'] = 1;
if (!$this->User->save($results)) {
echo 'Could not update account for User.id = ', $results['User']['id'], PHP_EOL;

View File

@ -73,11 +73,13 @@ class AppController extends Controller {
//'authorize' => array('Controller', // Added this line
//'Actions' => array('actionPath' => 'controllers')) // TODO ACL, 4: tell actionPath
),
'Security'
);
public $mispVersion = '2.3.0';
public function beforeFilter() {
$this->Security->blackHoleCallback = 'blackHole';
// send users away that are using ancient versions of IE
// Make sure to update this if IE 20 comes out :)
if(preg_match('/(?i)msie [2-8]/',$_SERVER['HTTP_USER_AGENT']) && !strpos($_SERVER['HTTP_USER_AGENT'], 'Opera')) throw new MethodNotAllowedException('You are using an unsecure and outdated version of IE, please download Google Chrome, Mozilla Firefox or update to a newer version of IE. If you are running IE9 or newer and still receive this error message, please make sure that you are not running your browser in compatibility mode. If you still have issues accessing the site, get in touch with your administration team at ' . Configure::read('MISP.contact'));
@ -87,28 +89,58 @@ class AppController extends Controller {
// disable CSRF for REST access
if (array_key_exists('Security', $this->components))
$this->Security->csrfCheck = false;
// Authenticate user with authkey in Authorization HTTP header
if (!empty($_SERVER['HTTP_AUTHORIZATION'])) {
$user = $this->checkAuthUser($_SERVER['HTTP_AUTHORIZATION']);
if ($user) {
// User found in the db, add the user info to the session
$this->Session->renew();
$this->Session->write(AuthComponent::$sessionKey, $user['User']);
} else {
// User not authenticated correctly
// reset the session information
$this->Session->destroy();
throw new ForbiddenException('The authentication key provided cannot be used for syncing.');
$found_misp_auth_key = false;
$authentication = explode(',', $_SERVER['HTTP_AUTHORIZATION']);
$user = false;
foreach ($authentication as $auth_key) {
if (preg_match('/^[a-zA-Z0-9]{40}$/', trim($auth_key))) {
$found_misp_auth_key = true;
$user = $this->checkAuthUser(trim($auth_key));
continue;
}
}
if ($found_misp_auth_key) {
if ($user) {
unset($user['User']['gpgkey']);
// User found in the db, add the user info to the session
$this->Session->renew();
$this->Session->write(AuthComponent::$sessionKey, $user['User']);
} else {
// User not authenticated correctly
// reset the session information
$this->Session->destroy();
throw new ForbiddenException('The authentication key provided cannot be used for syncing.');
}
unset($user);
}
}
} else if(!$this->Session->read(AuthComponent::$sessionKey)) {
// load authentication plugins from Configure::read('Security.auth')
$auth = Configure::read('Security.auth');
if($auth) {
$this->Auth->authenticate = array_merge($auth, $this->Auth->authenticate);
if($this->Auth->startup($this)) {
$user = $this->Auth->user();
if ($user) {
unset($user['gpgkey']);
// User found in the db, add the user info to the session
$this->Session->renew();
$this->Session->write(AuthComponent::$sessionKey, $user);
}
unset($user);
}
}
unset($auth);
}
// user must accept terms
//
if ($this->Session->check('Auth.User') && !$this->Auth->user('termsaccepted') && (!in_array($this->request->here, array('/users/terms', '/users/logout', '/users/login')))) {
if ($this->Session->check(AuthComponent::$sessionKey) && !$this->Auth->user('termsaccepted') && (!in_array($this->request->here, array('/users/terms', '/users/logout', '/users/login')))) {
$this->redirect(array('controller' => 'users', 'action' => 'terms', 'admin' => false));
}
if ($this->Session->check('Auth.User') && $this->Auth->user('change_pw') && (!in_array($this->request->here, array('/users/terms', '/users/change_pw', '/users/logout', '/users/login')))) {
if ($this->Session->check(AuthComponent::$sessionKey) && $this->Auth->user('change_pw') && (!in_array($this->request->here, array('/users/terms', '/users/change_pw', '/users/logout', '/users/login')))) {
$this->redirect(array('controller' => 'users', 'action' => 'change_pw', 'admin' => false));
}
@ -162,9 +194,15 @@ class AppController extends Controller {
$this->set('mispVersion', $this->mispVersion);
}
public function blackhole($type) {
if ($type === 'csrf') throw new BadRequestException(__d('cake_dev', $type));
throw new BadRequestException(__d('cake_dev', 'The request has been black-holed'));
}
public $userRole = null;
protected function _isJson(){
protected function _isJson($data=false){
if ($data) return (json_decode($data) != NULL) ? true : false;
return $this->request->header('Accept') === 'application/json';
}

View File

@ -1495,11 +1495,6 @@ class AttributesController extends AppController {
// ! - you can negate a search term. For example: google.com&&!mail would search for all attributes with value google.com but not ones that include mail. www.google.com would get returned, mail.google.com wouldn't.
public function restSearch($key='download', $value=false, $type=false, $category=false, $org=false, $tags=false, $from=false, $to=false) {
if ($tags) $tags = str_replace(';', ':', $tags);
if ($tags === 'null') $tags = null;
if ($value === 'null') $value = null;
if ($type === 'null') $type = null;
if ($category === 'null') $category = null;
if ($org === 'null') $org = null;
if ($key!=null && $key!='download') {
$user = $this->checkAuthUser($key);
} else {
@ -1530,6 +1525,13 @@ class AttributesController extends AppController {
else ${$p} = null;
}
}
$simpleFalse = array('value' , 'type', 'category', 'org', 'tags', 'from', 'to');
foreach ($simpleFalse as $sF) {
if (${$sF} === 'null' || ${$sF} == '0' || ${$sF} === false || strtolower(${$sF}) === 'false') ${$sF} = false;
}
if ($from) $from = $this->Attribute->Event->dateFieldCheck($from);
if ($to) $to = $this->Attribute->Event->dateFieldCheck($to);
if (!isset($this->request->params['ext']) || $this->request->params['ext'] !== 'json') {
$this->response->type('xml'); // set the content type
$this->layout = 'xml/default';
@ -1768,8 +1770,8 @@ class AttributesController extends AppController {
if (${$sF} === 'null' || ${$sF} == '0' || ${$sF} === false || strtolower(${$sF}) === 'false') ${$sF} = false;
}
if ($type === 'null' || $type === '0' || $type === 'false') $type = 'all';
if ($from && !preg_match('/^[0-9]{4}-[0-9]{2}-[0-9]{2}$/', $from)) $from = false;
if ($to && !preg_match('/^[0-9]{4}-[l0-9]{2}-[0-9]{2}$/', $from)) $from = false;
if ($from) $from = $this->Attribute->Event->dateFieldCheck($from);
if ($to) $to = $this->Attribute->Event->dateFieldCheck($to);
if ($key != 'download') {
// check if the key is valid -> search for users based on key
$user = $this->checkAuthUser($key);

View File

@ -467,6 +467,8 @@ class EventsController extends AppController {
if (!$this->Event->User->getPGP($this->Auth->user('id')) && Configure::read('GnuPG.onlyencrypted')) {
$this->Session->setFlash(__('No GPG key set in your profile. To receive emails, submit your public key in your profile.'));
} elseif ($this->Auth->user('autoalert') && !$this->Event->User->getPGP($this->Auth->user('id')) && Configure::read('GnuPG.bodyonlyencrypted')) {
$this->Session->setFlash(__('No GPG key set in your profile. To receive attributes in emails, submit your public key in your profile.'));
}
$this->set('eventDescriptions', $this->Event->fieldDescriptions);
$this->set('analysisLevels', $this->Event->analysisLevels);
@ -975,6 +977,8 @@ class EventsController extends AppController {
}
}
$this->request->data['Event']['date'] = date('Y-m-d');
// combobox for distribution
$distributions = array_keys($this->Event->distributionDescriptions);
$distributions = $this->_arrayToValuesIndexArray($distributions);
@ -1725,6 +1729,8 @@ class EventsController extends AppController {
foreach ($simpleFalse as $sF) {
if (${$sF} === 'null' || ${$sF} == '0' || ${$sF} === false || strtolower(${$sF}) === 'false') ${$sF} = false;
}
if ($from) $from = $this->Event->dateFieldCheck($from);
if ($to) $to = $this->Event->dateFieldCheck($to);
if ($tags) $tags = str_replace(';', ':', $tags);
$eventIdArray = array();
@ -1802,6 +1808,9 @@ class EventsController extends AppController {
foreach ($simpleFalse as $sF) {
if (${$sF} === 'null' || ${$sF} == '0' || ${$sF} === false || strtolower(${$sF}) === 'false') ${$sF} = false;
}
if ($from) $from = $this->Event->dateFieldCheck($from);
if ($to) $to = $this->Event->dateFieldCheck($to);
if ($tags) $tags = str_replace(';', ':', $tags);
// backwards compatibility, swap key and format
if ($format != 'snort' && $format != 'suricata') {
@ -1837,6 +1846,9 @@ class EventsController extends AppController {
foreach ($simpleFalse as $sF) {
if (${$sF} === 'null' || ${$sF} == '0' || ${$sF} === false || strtolower(${$sF}) === 'false') ${$sF} = false;
}
if ($from) $from = $this->Event->dateFieldCheck($from);
if ($to) $to = $this->Event->dateFieldCheck($to);
if ($tags) $tags = str_replace(';', ':', $tags);
$this->response->type('txt'); // set the content type
$this->header('Content-Disposition: download; filename="misp.' . $type . '.rules"');
@ -1869,6 +1881,9 @@ class EventsController extends AppController {
foreach ($simpleFalse as $sF) {
if (${$sF} === 'null' || ${$sF} == '0' || ${$sF} === false || strtolower(${$sF}) === 'false') ${$sF} = false;
}
if ($from) $from = $this->Event->dateFieldCheck($from);
if ($to) $to = $this->Event->dateFieldCheck($to);
if ($tags) $tags = str_replace(';', ':', $tags);
$list = array();
if ($key != 'download') {
@ -2399,6 +2414,9 @@ class EventsController extends AppController {
foreach ($simpleFalse as $sF) {
if (${$sF} === 'null' || ${$sF} == '0' || ${$sF} === false || strtolower(${$sF}) === 'false') ${$sF} = false;
}
if ($from) $from = $this->Event->dateFieldCheck($from);
if ($to) $to = $this->Event->dateFieldCheck($to);
if ($tags) $tags = str_replace(';', ':', $tags);
if ($searchall === 'true') $searchall = "1";
@ -2974,6 +2992,8 @@ class EventsController extends AppController {
foreach ($simpleFalse as $sF) {
if (${$sF} === 'null' || ${$sF} == '0' || ${$sF} === false || strtolower(${$sF}) === 'false') ${$sF} = false;
}
if ($from) $from = $this->Event->dateFieldCheck($from);
if ($to) $to = $this->Event->dateFieldCheck($to);
// set null if a null string is passed
$numeric = false;

View File

@ -61,6 +61,7 @@ class PostsController extends AppController {
}
$distribution = $this->Event->data['Event']['distribution'];
$org = $this->Event->data['Event']['org'];
$event_id = $this->Event->data['Event']['id'];
break;
case 'thread' :
$target_thread_id = $target_id;
@ -75,6 +76,7 @@ class PostsController extends AppController {
}
}
$title = $this->Thread->data['Thread']['title'];
$event_id = $this->Thread->data['Thread']['event_id'];
}
break;
case 'post' :
@ -110,10 +112,9 @@ class PostsController extends AppController {
if ($target_thread_id == null) {
// We have a post that was posted in a new thread. This could also mean that someone created the first post related to an event!
$this->Thread->create();
// Take the title from above and the id of the event as event_id if we are adding a post to an event.
// Take the title from above if we are adding a post to an event.
if ($target_type === 'event') {
$title = $eventDiscussionTitle;
$event_id = $this->Event->data['Event']['id'];
}
$newThread = array(
'date_created' => date('Y/m/d H:i:s'),
@ -150,6 +151,7 @@ class PostsController extends AppController {
$this->Thread->read(null, $target_thread_id);
$this->Thread->updateAfterPostChange(true);
$this->Session->setFlash(__('Post added'));
$this->Post->sendPostsEmailRouter($this->Auth->user('id'), $this->Post->getId(), $event_id, $title, $this->request->data['Post']['message']);
$this->redirect(array('action' => 'view', $this->Post->getId()));
} else {
$this->Session->setFlash('The post could not be added.');
@ -277,4 +279,4 @@ class PostsController extends AppController {
}
?>

View File

@ -170,16 +170,15 @@ class ServersController extends AppController {
}
if (!Configure::read('MISP.background_jobs')) {
$result = $this->Server->pull($this->Auth->user(), $id, $technique, $s);
// error codes
if (is_numeric($result)) {
switch ($result) {
if (isset($result[0]) && is_numeric($result[0])) {
switch ($result[0]) {
case '1' :
$this->Session->setFlash(__('Not authorised. This is either due to an invalid auth key, or due to the sync user not having authentication permissions enabled on the remote server.'));
$this->Session->setFlash(__('Not authorised. This is either due to an invalid auth key, or due to the sync user not having authentication permissions enabled on the remote server. Another reason could be an incorrect sync server setting.'));
$this->redirect(array('action' => 'index'));
break;
case '2' :
$this->Session->setFlash($eventIds);
$this->Session->setFlash($result[1]);
$this->redirect(array('action' => 'index'));
break;
case '3' :
@ -526,7 +525,8 @@ class ServersController extends AppController {
}
if ($this->request->is('get')) {
if ($found != null) {
$found['value'] = Configure::read($setting);
$value = Configure::read($setting);
if ($value) $found['value'] = $value;
$found['setting'] = $setting;
}
$this->set('setting', $found);

View File

@ -805,165 +805,91 @@ class UsersController extends AppController {
}
public function admin_email() {
if (!$this->_isSiteAdmin()) {
throw new MethodNotAllowedException();
if (!$this->_isAdmin()) throw new MethodNotAllowedException();
// User has filled in his contact form, send out the email.
if ($this->request->is('post') || $this->request->is('put')) {
$conditions = array();
if (!$this->_isSiteAdmin()) $conditions = array('org' => $this->Auth->user('org'));
if ($this->request->data['User']['recipient'] != 1) $conditions['id'] = $this->request->data['User']['recipientEmailList'];
$users = $this->User->find('all', array('recursive' => -1, 'order' => array('email ASC'), 'conditions' => $conditions));
$this->request->data['User']['message'] = $this->User->adminMessageResolve($this->request->data['User']['message']);
$failures = '';
foreach ($users as $user) {
$password = $this->User->generateRandomPassword();
$body = str_replace('$password', $password, $this->request->data['User']['message']);
$body = str_replace('$username', $user['User']['email'], $body);
$result = $this->User->sendEmail($user, $body, false, $this->request->data['User']['subject']);
// if sending successful and action was a password change, update the user's password.
if ($result && $this->request->data['User']['action'] != '0') {
$this->User->id = $user['User']['id'];
$this->User->saveField('password', $password);
$this->User->saveField('change_pw', '1');
}
if (!$result) {
if ($failures != '') $failures .= ', ';
$failures .= $user['User']['email'];
}
}
if ($failures != '') $this->Session->setFlash(__('E-mails sent, but failed to deliver the messages to the following recipients: ' . $failures));
else $this->Session->setFlash(__('E-mails sent.'));
}
$this->User->recursive = 0;
$temp = $this->User->find('all', array('fields' => array('email', 'gpgkey'), 'order' => array('email ASC')));
$conditions = array();
if (!$this->_isSiteAdmin()) $conditions = array('org' => $this->Auth->user('org'));
$temp = $this->User->find('all', array('recursive' => -1, 'fields' => array('id', 'email'), 'order' => array('email ASC'), 'conditions' => $conditions));
$emails = array();
$gpgKeys = array();
// save all the emails of the users and set it for the dropdown list in the form
foreach ($temp as $user) {
array_push($emails, $user['User']['email']);
array_push($gpgKeys, $user['User']['gpgkey']);
$emails[$user['User']['id']] = $user['User']['email'];
}
$this->set('users', $temp);
$this->set('recipientEmail', $emails);
// User has filled in his contact form, send out the email.
if ($this->request->is('post') || $this->request->is('put')) {
$message1 = null;
$message2 = null;
$recipients = array();
$messageP = array();
// Formulating the message and the subject that will be common to the e-mail(s) sent
if ($this->request->data['User']['action'] == '0') {
// Custom message
$subject = $this->request->data['User']['subject'];
$message1 .= $this->request->data['User']['message'];
} else {
// Temp password
if ($this->request->data['User']['customMessage']) {
$message1 .= $this->request->data['User']['message'];
} else {
$message1 .= "Dear MISP user,\n\nA password reset has been triggered for your account. Use the below provided temporary password to log into MISP at ";
$message1 .= Configure::read('MISP.baseurl');
$message1 .= ", where you will be prompted to manually change your password to something of your own choice.";
}
//$message .= "\n\nYour temporary password: " . $password;
$subject = 'Password reset on ' . Configure::read('MISP.org') . ' MISP';
}
if (Configure::read('MISP.contact')) {
$message2 .= "\n\nIf you have any questions, contact us at: " . Configure::read('MISP.contact') . ".";
}
$message2 .= "\n\nBest Regards,\n" . Configure::read('MISP.org') . ' MISP support';
// Return an error message if the action is a password reset for a new user
if ($this->request->data['User']['recipient'] == 2 && $this->request->data['User']['action'] == '1') {
$this->Session->setFlash(__('Cannot reset the password of a user that doesn\'t exist.'));
$this->redirect(array('action' => 'email', 'admin' => true));
}
// Setting up the list of recipient(s) based on the setting and creating the final message for each user, including the password
// If the recipient is all users, and the action to create a password, create it and for each user and squeeze it between the main message and the signature
if ($this->request->data['User']['recipient'] == 0) {
$recipients = $emails;
$recipientGPG = $gpgKeys;
if ($this->request->data['User']['action'] == '1') {
$i = 0;
foreach ($recipients as $rec) {
$password = $this->User->generateRandomPassword();
$messageP = "\n\nYour temporary password: " . $password;
$message[$i] = $message1 . $messageP . $message2;
$recipientPass[$i] = $password;
$i++;
}
} else {
$i = 0;
foreach ($recipients as $rec) {
$message[$i] = $message1;
$i++;
}
}
}
// If the recipient is a user, and the action to create a password, create it and squeeze it between the main message and the signature
if ($this->request->data['User']['recipient'] == 1) {
$recipients[0] = $emails[$this->request->data['User']['recipientEmailList']];
$recipientGPG[0] = $gpgKeys[$this->request->data['User']['recipientEmailList']];
if ($this->request->data['User']['action'] == '1') {
$password = $this->User->generateRandomPassword();
$message[0] = $message1 . "\n\nYour temporary password: " . $password . $message2;
$recipientPass[0] = $password;
} else {
$message[0] = $message1;
}
}
require_once 'Crypt/GPG.php';
$i = 0;
$this->Log = ClassRegistry::init('Log');
foreach ($recipients as $recipient) {
if (!empty($recipientGPG[$i])) {
$gpg = new Crypt_GPG(array('homedir' => Configure::read('GnuPG.homedir'))); // , 'debug' => true
$gpg->addSignKey(Configure::read('GnuPG.email'), Configure::read('GnuPG.password'));
$messageSigned = $gpg->sign($message[$i], Crypt_GPG::SIGN_MODE_CLEAR);
$keyImportOutput = $gpg->importKey($recipientGPG[$i]);
try {
$gpg = new Crypt_GPG(array('homedir' => Configure::read('GnuPG.homedir')));
$gpg->addEncryptKey($keyImportOutput['fingerprint']); // use the key that was given in the import
$encryptedMessage = $gpg->encrypt($messageSigned, true);
} catch (Exception $e){
// catch errors like expired PGP keys
$this->log($e->getMessage());
// no need to return here, as we want to send out mails to the other users if GPG encryption fails for a single user
}
} else {
$encryptedMessage = $message[$i];
}
// prepare the email
$this->Email->from = Configure::read('MISP.email');
$this->Email->to = $recipients[$i];
$this->Email->subject = $subject;
//$this->Email->delivery = 'debug'; // do not really send out mails, only display it on the screen
$this->Email->template = 'body';
$this->Email->sendAs = 'text'; // both text or html
$this->set('body', $encryptedMessage);
// send it
$result = $this->Email->send();
$this->Log->create();
if ($result) {
$this->Log->save(array(
'org' => $this->Auth->user('org'),
'model' => 'User',
'model_id' => $this->Auth->user('id'),
'email' => $this->Auth->user('email'),
'action' => 'admin_email',
'title' => 'Admin email to ' . $recipients[$i] . ' sent, titled "' . $subject . '".',
'change' => null,
));
} else {
$this->Log->save(array(
'org' => $this->Auth->user('org'),
'model' => 'User',
'model_id' => $this->Auth->user('id'),
'email' => $this->Auth->user('email'),
'action' => 'admin_email',
'title' => 'Admin email to ' . $recipients[$i] . ' failed.',
'change' => null,
));
}
// if sending successful and action was a password change, update the user's password.
if ($result && $this->request->data['User']['action'] == '1') {
$this->User->recursive = 0;
$temp = $this->User->findByEmail($recipients[$i]);
$this->User->id = $temp['User']['id'];
$this->User->read();
$this->User->saveField('password', $recipientPass[$i]);
$this->User->saveField('change_pw', '1');
}
// If you wish to send multiple emails using a loop, you'll need
// to reset the email fields using the reset method of the Email component.
$this->Email->reset();
$i++;
}
$this->Session->setFlash(__('E-mails sent.'));
$this->set('org', Configure::read('MISP.org'));
$textsToFetch = array('newUserText', 'passwordResetText');
$this->loadModel('Server');
foreach ($textsToFetch as $text) {
${$text} = Configure::read('MISP.' . $text);
if (!${$text}) ${$text} = $this->Server->serverSettings['MISP'][$text]['value'];
$this->set($text, ${$text});
}
// User didn't see the contact form yet. Present it to him.
}
public function initiatePasswordReset($id, $firstTime = false) {
if (!$this->_isAdmin()) throw new MethodNotAllowedException('You are not authorised to do that.');
$user = $this->User->find('first', array(
'conditions' => array('id' => $id),
'recursive' => -1
));
if (!$this->_isSiteAdmin() && $this->Auth->user('org') != $user['User']['org']) throw new MethodNotAllowedException('You are not authorised to do that.');
if ($this->request->is('post')) {
$org = Configure::read('MISP.org');
$options = array('passwordResetText', 'newUserText');
$subjects = array('[' . $org . ' MISP] New user registration', '[' . $org . ' MISP] Password reset');
$textToFetch = $options[($firstTime ? 1 : 0)];
$subject = $subjects[($firstTime ? 1 : 0)];
$this->loadModel('Server');
$body = Configure::read('MISP.' . $textToFetch);
if (!$body) $body = $this->Server->serverSettings['MISP'][$textToFetch]['value'];
$body = $this->User->adminMessageResolve($body);
$password = $this->User->generateRandomPassword();
$body = str_replace('$password', $password, $body);
$body = str_replace('$username', $user['User']['email'], $body);
$result = $this->User->sendEmail($user, $body, false, $subject);
if ($result) {
$this->User->id = $user['User']['id'];
$this->User->saveField('password', $password);
$this->User->saveField('change_pw', '1');
return new CakeResponse(array('body'=> json_encode(array('saved' => true, 'success' => 'New credentials sent.')),'status'=>200));
}
return new CakeResponse(array('body'=> json_encode(array('saved' => false, 'errors' => 'There was an error notifying the user. His/her credentials were not altered.')),'status'=>200));
} else {
$this->layout = 'ajax';
$this->set('user', $user);
$this->set('firstTime', $firstTime);
$this->render('ajax/passwordResetConfirmationForm');
}
}
// shows some statistics about the instance
public function statistics() {

View File

@ -59,13 +59,14 @@ class ComplexTypeTool {
}
public function checkFreeText($input) {
$iocArray = preg_split("/\r\n|\n|\r/", $input);
$iocArray = preg_split("/\r\n|\n|\r|\s|\s+/", $input);
$resultArray = array();
foreach ($iocArray as $ioc) {
$ioc = trim($ioc);
$ioc = preg_replace('/\p{C}+/u', '', $ioc);
if (empty($ioc)) continue;
$typeArray = $this->__resolveType($ioc);
if ($typeArray === false) continue;
$temp = $typeArray;
$temp['value'] = $ioc;
$resultArray[] = $temp;
@ -114,7 +115,7 @@ class ComplexTypeTool {
return array('types' => array('domain'), 'to_ids' => true, 'default_type' => 'domain');
}
} else {
if (!preg_match('/[?:<>|\\*:\/@]/', $input)) {
if (!preg_match('/[?:<>|\\*:\/@]/', $input) && strpos($input, '.') != 0 && strpos($input, '.') != (strlen($input)-1)) {
return array('types' => array('filename'), 'to_ids' => true, 'default_type' => 'filename');
}
}
@ -123,7 +124,7 @@ class ComplexTypeTool {
if (strpos($input, '\\') !== false) {
$temp = explode('\\', $input);
if (strpos($temp[count($temp)-1], '.')) {
if (!preg_match('/[?:<>|\\*:\/]/', $temp[count($temp)-1])) {
if (!preg_match('/[?:<>|\\*:\/]/', $temp[count($temp)-1]) && strpos($temp[count($temp)-1], '.') != 0 && strpos($temp[count($temp)-1], '.') != (strlen($temp[count($temp)-1])-1)) {
return array('types' => array('filename'), 'category' => 'Payload installation', 'to_ids' => false, 'default_type' => 'filename');
}
} else {
@ -138,6 +139,6 @@ class ComplexTypeTool {
// check for CVE
if (preg_match("#^cve-[0-9]{4}-[0-9]{4,9}$#i", $input)) return array('types' => array('vulnerability'), 'category' => 'External analysis', 'to_ids' => false, 'default_type' => 'vulnerability');
return array('types' => array('text'), 'category' => 'Other', 'to_ids' => false, 'default_type' => 'text');
return false;
}
}

View File

@ -12,7 +12,7 @@ class SyncTool {
$HttpSocket = new HttpSocket($params);
$proxy = Configure::read('Proxy');
$HttpSocket->configProxy($proxy['host'], $proxy['port'], $proxy['method'], $proxy['user'], $proxy['password']);
if ($proxy) $HttpSocket->configProxy($proxy['host'], $proxy['port'], $proxy['method'], $proxy['user'], $proxy['password']);
return $HttpSocket;
}

View File

@ -2,6 +2,7 @@
App::uses('AppModel', 'Model');
App::uses('CakeEmail', 'Network/Email');
App::import('Controller', 'Attributes');
Configure::load('config'); // This is needed to load GnuPG.bodyonlyencrypted
/**
* Event Model
*
@ -1169,6 +1170,8 @@ class Event extends AppModel {
} else {
$subject = '';
}
$subject = "[" . Configure::read('MISP.org') . " MISP] Event " . $id . " - " . $subject . $event['ThreatLevel']['name'] . " - TLP Amber";
$body .= $bodyTempOther; // append the 'other' attribute types to the bottom.
$body .= '==============================================' . "\n";
// find out whether the event is private, to limit the alerted user's list to the org only
@ -1177,98 +1180,28 @@ class Event extends AppModel {
} else {
$eventIsPrivate = false;
}
// sign the body
require_once 'Crypt/GPG.php';
try {
$gpg = new Crypt_GPG(array('homedir' => Configure::read('GnuPG.homedir'))); // , 'debug' => true
$gpg->addSignKey(Configure::read('GnuPG.email'), Configure::read('GnuPG.password'));
$bodySigned = $gpg->sign($body, Crypt_GPG::SIGN_MODE_CLEAR);
//
// Build a list of the recipients that get a non-encrypted mail
// But only do this if it is allowed in the bootstrap.php file.
//
if ($eventIsPrivate) {
$conditions = array('User.autoalert' => 1, 'User.gpgkey =' => "", 'User.org =' => $event['Event']['org']);
} else {
$conditions = array('User.autoalert' => 1, 'User.gpgkey =' => "");
}
if (!Configure::read('GnuPG.onlyencrypted')) {
$alertUsers = $this->User->find('all', array(
'conditions' => $conditions,
'recursive' => 0,
));
$max = count($alertUsers);
foreach ($alertUsers as $k => &$user) {
// prepare the the unencrypted email
$Email = new CakeEmail();
$Email->from(Configure::read('MISP.email'));
$Email->to($user['User']['email']);
$Email->subject("[" . Configure::read('MISP.org') . " MISP] Event " . $id . " - " . $subject . $event['ThreatLevel']['name'] . " - TLP Amber");
$Email->emailFormat('text'); // both text or html
// send it
$Email->send($bodySigned);
$Email->reset();
if ($processId) {
$this->Job->id = $processId;
$this->Job->saveField('progress', $k / $max * 50);
}
}
}
//
// Build a list of the recipients that wish to receive encrypted mails.
//
if ($eventIsPrivate) {
$conditions = array('User.autoalert' => 1, 'User.gpgkey !=' => "", 'User.org =' => $event['Event']['org']);
} else {
$conditions = array('User.autoalert' => 1, 'User.gpgkey !=' => "");
$bodyNoEnc = "A new or modified event was just published on " . Configure::read('MISP.baseurl') . "/events/view/" . $event['Event']['id'];
$conditions = array('User.autoalert' => 1);
if ($eventIsPrivate) $conditions['User.org'] = $event['Event']['org'];
$alertUsers = $this->User->find('all', array(
'conditions' => $conditions,
'recursive' => -1,
));
$max = count($alertUsers);
foreach ($alertUsers as $k => &$user) {
$this->User->sendEmail($user, $body, $bodyNoEnc, $subject);
if ($processId) {
$this->Job->id = $processId;
$this->Job->saveField('progress', $k / $max * 100);
}
$alertUsers = $this->User->find('all', array(
'conditions' => $conditions,
'recursive' => 0,
)
);
$max = count($alertUsers);
// encrypt the mail for each user and send it separately
foreach ($alertUsers as $k => &$user) {
// send the email
$Email = new CakeEmail();
$Email->from(Configure::read('MISP.email'));
$Email->to($user['User']['email']);
$Email->subject("[" . Configure::read('MISP.org') . " MISP] Event " . $id . " - " . $subject . " - " . $event['ThreatLevel']['name'] . " - TLP Amber");
$Email->emailFormat('text'); // both text or html
// import the key of the user into the keyring
// this is not really necessary, but it enables us to find
// the correct key-id even if it is not the same as the emailaddress
$keyImportOutput = $gpg->importKey($user['User']['gpgkey']);
// say what key should be used to encrypt
try {
$gpg = new Crypt_GPG(array('homedir' => Configure::read('GnuPG.homedir')));
$gpg->addEncryptKey($keyImportOutput['fingerprint']); // use the key that was given in the import
$bodyEncSig = $gpg->encrypt($bodySigned, true);
$Email->send($bodyEncSig);
} catch (Exception $e){
// catch errors like expired PGP keys
$this->log($e->getMessage());
// no need to return here, as we want to send out mails to the other users if GPG encryption fails for a single user
}
// If you wish to send multiple emails using a loop, you'll need
// to reset the email fields using the reset method of the Email component.
$Email->reset();
if ($processId) {
$this->Job->saveField('progress', ($k / $max * 50) + 50);
}
}
} catch (Exception $e){
// catch errors like expired PGP keys
$this->log($e->getMessage());
return $e->getMessage();
}
if ($processId) {
$this->Job->saveField('message', 'Mails sent.');
}
// LATER check if sending email succeeded and return appropriate result
return true;
}
if ($processId) $this->Job->saveField('message', 'Mails sent.');
// LATER check if sending email succeeded and return appropriate result
return true;
}
public function sendContactEmail($id, $message, $all, $user, $isSiteAdmin) {
@ -1279,7 +1212,7 @@ class Event extends AppModel {
//Insert extra field here: alertOrg or something, then foreach all the org members
//limit this array to users with contactalerts turned on!
$orgMembers = array();
$this->User->recursive = 0;
$this->User->recursive = -1;
$temp = $this->User->findAllByOrg($event['Event']['org'], array('email', 'gpgkey', 'contactalert', 'id'));
foreach ($temp as $tempElement) {
if ($tempElement['User']['contactalert'] || $tempElement['User']['id'] == $event['Event']['user_id']) {
@ -1310,97 +1243,44 @@ class Event extends AppModel {
// LATER place event-to-email-layout in a function
$appendlen = 20;
$body .= 'URL : ' . Configure::read('MISP.baseurl') . '/events/view/' . $event['Event']['id'] . "\n";
$body .= 'Event : ' . $event['Event']['id'] . "\n";
$body .= 'Date : ' . $event['Event']['date'] . "\n";
$bodyevent = $body;
$bodyevent .= 'Event : ' . $event['Event']['id'] . "\n";
$bodyevent .= 'Date : ' . $event['Event']['date'] . "\n";
if (Configure::read('MISP.showorg')) {
$body .= 'Reported by : ' . $event['Event']['org'] . "\n";
$bodyevent .= 'Reported by : ' . $event['Event']['org'] . "\n";
}
$body .= 'Risk : ' . $event['ThreatLevel']['name'] . "\n";
$body .= 'Analysis : ' . $event['Event']['analysis'] . "\n";
$bodyevent .= 'Risk : ' . $event['ThreatLevel']['name'] . "\n";
$bodyevent .= 'Analysis : ' . $event['Event']['analysis'] . "\n";
$relatedEvents = $this->getRelatedEvents($user['User'], $isSiteAdmin);
if (!empty($relatedEvents)) {
foreach ($relatedEvents as &$relatedEvent) {
$body .= 'Related to : ' . Configure::read('MISP.baseurl') . '/events/view/' . $relatedEvent['Event']['id'] . ' (' . $relatedEvent['Event']['date'] . ')' . "\n";
$bodyevent .= 'Related to : ' . Configure::read('MISP.baseurl') . '/events/view/' . $relatedEvent['Event']['id'] . ' (' . $relatedEvent['Event']['date'] . ')' . "\n";
}
}
$body .= 'Info : ' . "\n";
$body .= $event['Event']['info'] . "\n";
$body .= "\n";
$body .= 'Attributes :' . "\n";
$bodyevent .= 'Info : ' . "\n";
$bodyevent .= $event['Event']['info'] . "\n";
$bodyevent .= "\n";
$bodyevent .= 'Attributes :' . "\n";
$bodyTempOther = "";
if (!empty($event['Attribute'])) {
foreach ($event['Attribute'] as &$attribute) {
$line = '- ' . $attribute['type'] . str_repeat(' ', $appendlen - 2 - strlen( $attribute['type'])) . ': ' . $attribute['value'] . "\n";
if ('other' == $attribute['type']) // append the 'other' attribute types to the bottom.
$bodyTempOther .= $line;
else $body .= $line;
else $bodyevent .= $line;
}
}
$body .= "\n";
$body .= $bodyTempOther; // append the 'other' attribute types to the bottom.
$Email = new CakeEmail();
// sign the body
require_once 'Crypt/GPG.php';
$gpg = new Crypt_GPG(array('homedir' => Configure::read('GnuPG.homedir'))); // , 'debug' => true
$gpg->addSignKey(Configure::read('GnuPG.email'), Configure::read('GnuPG.password'));
$bodySigned = $gpg->sign($body, Crypt_GPG::SIGN_MODE_CLEAR);
// Add the GPG key of the user as attachment
// LATER sign the attached GPG key
if ($user['User']['gpgkey'] != null) {
// save the gpg key to a temporary file
$tmpfname = tempnam(TMP, "GPGkey");
$handle = fopen($tmpfname, "w");
fwrite($handle, $user['User']['gpgkey']);
fclose($handle);
// attach it
$Email->attachments(array(
'gpgkey.asc' => $tmpfname
));
}
$bodyevent .= "\n";
$bodyevent .= $bodyTempOther; // append the 'other' attribute types to the bottom.
foreach ($orgMembers as &$reporter) {
if (!empty($reporter['User']['gpgkey'])) {
// import the key of the user into the keyring
// this isn't really necessary, but it gives it the fingerprint necessary for the next step
$keyImportOutput = $gpg->importKey($reporter['User']['gpgkey']);
// say what key should be used to encrypt
try {
$gpg = new Crypt_GPG(array('homedir' => Configure::read('GnuPG.homedir')));
$gpg->addEncryptKey($keyImportOutput['fingerprint']); // use the key that was given in the import
$bodyEncSig = $gpg->encrypt($bodySigned, true);
} catch (Exception $e){
// catch errors like expired PGP keys
$this->log($e->getMessage());
// no need to return here, as we want to send out mails to the other users if GPG encryption fails for a single user
}
} else {
$bodyEncSig = $bodySigned;
// FIXME should I allow sending unencrypted "contact" mails to people if they didn't import they GPG key?
$bodyNoEnc = false;
if (Configure::read('GnuPG.bodyonlyencrypted') && empty($reporter['User']['gpgkey'])) {
$bodyNoEnc = $body;
}
$Email->from(Configure::read('MISP.email'));
$Email->replyTo($user['User']['email']);
$Email->to($reporter['User']['email']);
$Email->subject("[" . Configure::read('MISP.org') . " MISP] Need info about event " . $id . " - TLP Amber");
//$this->Email->delivery = 'debug'; // do not really send out mails, only display it on the screen
$Email->emailFormat('text'); // both text or html
// Add the GPG key of the user as attachment
// LATER sign the attached GPG key
if ($user['User']['gpgkey'] != null) {
// attach the gpg key
$Email->attachments(array(
'gpgkey.asc' => $tmpfname
));
}
// send it
$result = $Email->send($bodyEncSig);
// If you wish to send multiple emails using a loop, you'll need
// to reset the email fields using the reset method of the Email component.
$Email->reset();
$subject = "[" . Configure::read('MISP.org') . " MISP] Need info about event " . $id . " - TLP Amber";
$result = $this->User->sendEmail($reporter, $bodyevent, $bodyNoEnc, $subject, $user);
}
// remove the temporary gpg file
if ($user['User']['gpgkey'] != null) unlink($tmpfname);
return $result;
}
@ -1916,4 +1796,12 @@ class Event extends AppModel {
}
return $fn;
}
// expects a date string in the DD-MM-YYYY format
// returns the passed string or false if the format is invalid
// based on the fix provided by stevengoosensB
public function dateFieldCheck($date) {
// regex check for from / to field by stevengoossensB
return (preg_match('/^[0-9]{4}-(0[1-9]|1[012])-(0[1-9]|1[0-9]|2[0-9]|3[01])$/', $date)) ? $date : false;
}
}

View File

@ -23,7 +23,8 @@ class Log extends AppModel {
'pull',
'push',
'blacklisted',
'admin_email'
'admin_email',
'email'
)),
'message' => 'Options : ...'
)

View File

@ -1,6 +1,7 @@
<?php
App::uses('AppModel', 'Model');
App::uses('CakeEmail', 'Network/Email');
/**
* Post Model
@ -16,4 +17,100 @@ class Post extends AppModel {
)
);
public function sendPostsEmailRouter($user_id, $post_id, $event_id, $title, $message, $JobId = false) {
if (Configure::read('MISP.background_jobs')) {
$user = $this->User->findById($user_id);
$job = ClassRegistry::init('Job');
$job->create();
$data = array(
'worker' => 'email',
'job_type' => 'posts_alert',
'job_input' => 'Post: ' . $post_id,
'status' => 0,
'retries' => 0,
'org' => $user['User']['org'],
'message' => 'Sending..',
);
$job->save($data);
$jobId = $job->id;
$process_id = CakeResque::enqueue(
'email',
'EventShell',
array('postsemail', $user_id, $post_id, $event_id, $title, $message, $jobId)
);
$job->saveField('process_id', $process_id);
return true;
} else {
$result = $this->sendPostsEmail($user_id, $post_id, $event_id, $title, $message);
return $result;
}
}
public function sendPostsEmail($user_id, $post_id, $event_id, $title, $message) {
// fetch the post
$post = $this->read(null, $post_id);
$this->User = ClassRegistry::init('User');
// If the post belongs to an event, E-mail all users in the org that have contactalert set
if ($event_id) {
$this->Event = ClassRegistry::init('Event');;
$event = $this->Event->read(null, $event_id);
//Insert extra field here: alertOrg or something, then foreach all the org members
//limit this array to users with contactalerts turned on!
$orgMembers = array();
$this->User->recursive = -1;
$temp = $this->User->findAllByOrg($event['Event']['org'], array('email', 'gpgkey', 'contactalert', 'id'));
foreach ($temp as $tempElement) {
if ($tempElement['User']['id'] != $user_id && ($tempElement['User']['contactalert'] || $tempElement['User']['id'] == $event['Event']['user_id'])) {
array_push($orgMembers, $tempElement);
}
}
} else {
// Not an event: E-mail the user that started the thread
$thread = $this->Thread->read(null, $post['Post']['thread_id']);
if ($thread['Thread']['user_id'] == $user_id ) {
$orgMembers = array();
} else {
$orgMembers = $this->User->findAllById($thread['Thread']['user_id'], array('email', 'gpgkey', 'contactalert', 'id'));
}
}
// Add all users who posted in this thread
$temp = $this->findAllByThreadId($post['Post']['thread_id'],array('user_id'));
foreach ($temp as $tempElement) {
$user = $this->User->findById($tempElement['Post']['user_id'], array('email', 'gpgkey', 'contactalert', 'id'));
if(!empty($user) && $user['User']['id'] != $user_id && !in_array($user, $orgMembers)) {
array_push($orgMembers, $user);
}
}
// The mail body, h() is NOT needed as we are sending plain-text mails.
$body = "";
$body .= "Hello, \n";
$body .= "\n";
$body .= "Someone just posted to a MISP discussion you participated in.\n";
$body .= "\n";
$body .= "The full discussion can be found at: \n";
$body .= Configure::read('MISP.baseurl') . '/posts/view/' . $post['Post']['id'] . "\n";
// body containing all details ($title and $message)
$bodyDetail = "";
$bodyDetail .= "Hello, \n";
$bodyDetail .= "\n";
$bodyDetail .= "Someone just posted to a MISP discussion you participated in with title:\n";
$bodyDetail .= $title . "\n";
$bodyDetail .= "\n";
$bodyDetail .= "The full discussion can be found at: \n";
$bodyDetail .= Configure::read('MISP.baseurl') . '/posts/view/' . $post['Post']['id'] . "\n";
$bodyDetail .= "\n";
$bodyDetail .= "The following message was added: \n";
$bodyDetail .= "\n";
$bodyDetail .= $message . "\n";
$subject = "[" . Configure::read('MISP.org') . " MISP] New post in discussion " . $post['Post']['thread_id'] . " - TLP Amber";
foreach ($orgMembers as &$recipient) {
$result = $this->User->sendEmail($recipient, $bodyDetail, $body, $subject);
}
return $result;
}
}

View File

@ -283,6 +283,14 @@ class Server extends AppModel {
'test' => 'testBool',
'type' => 'boolean',
),
'extended_alert_subject' => array(
'level' => 1,
'description' => 'enabling this flag will allow the event description to be transmitted in the alert e-mail\'s subject. Be aware that this is not encrypted by PGP, so only enable it if you accept that part of the event description will be sent out in clear-text.',
'value' => false,
'errorMessage' => '',
'test' => 'testBool',
'type' => 'boolean'
),
'default_event_distribution' => array(
'level' => 0,
'description' => 'The default distribution setting for events (0-3).',
@ -389,12 +397,38 @@ class Server extends AppModel {
'test' => 'testBool',
'type' => 'boolean'
),
'newUserText' => array(
'level' => 1,
'bigField' => true,
'description' => 'The message sent to the user after account creation (has to be sent manually from the administration interface). Use \\n for line-breaks. The following variables will be automatically replaced in the text: $password = a new temporary password that MISP generates, $username = the user\'s e-mail address, $misp = the url of this instance, $org = the organisation that the instance belongs to, as set in MISP.org, $contact = the e-mail address used to contact the support team, as set in MISP.contact. For example, "the password for $username is $password" would appear to a user with the e-mail address user@misp.org as "the password for user@misp.org is hNamJae81".',
'value' => 'Dear new MISP user,\n\nWe would hereby like to welcome you to the $org MISP community.\n\n Use the credentials below to log into MISP at $misp, where you will be prompted to manually change your password to something of your own choice.\n\nUsername: $username\nPassword: $password\n\nIf you have any questions, don\'t hesitate to contact us at: $contact.\n\nBest regards,\nYour $org MISP support team',
'errorMessage' => '',
'test' => 'testPasswordResetText',
'type' => 'string'
),
'passwordResetText' => array(
'level' => 1,
'bigField' => true,
'description' => 'The message sent to the users when a password reset is triggered. Use \\n for line-breaks. The following variables will be automatically replaced in the text: $password = a new temporary password that MISP generates, $username = the user\'s e-mail address, $misp = the url of this instance, $contact = the e-mail address used to contact the support team, as set in MISP.contact. For example, "the password for $username is $password" would appear to a user with the e-mail address user@misp.org as "the password for user@misp.org is hNamJae81".',
'value' => 'Dear MISP user,\n\nA password reset has been triggered for your account. Use the below provided temporary password to log into MISP at $misp, where you will be prompted to manually change your password to something of your own choice.\n\nUsername: $username\nYour temporary password: $password\n\nIf you have any questions, don\'t hesitate to contact us at: $contact.\n\nBest regards,\nYour $org MISP support team',
'errorMessage' => '',
'test' => 'testPasswordResetText',
'type' => 'string'
),
),
'GnuPG' => array(
'branch' => 1,
'onlyencrypted' => array(
'level' => 0,
'description' => 'Allow unencrypted e-mails to be sent to users that don\'t have a PGP key.',
'description' => 'Allow (false) unencrypted e-mails to be sent to users that don\'t have a PGP key.',
'value' => '',
'errorMessage' => '',
'test' => 'testBool',
'type' => 'boolean',
),
'bodyonlyencrypted' => array(
'level' => 2,
'description' => 'Allow (false) the body of unencrypted e-mails to contain details about the event.',
'value' => '',
'errorMessage' => '',
'test' => 'testBool',
@ -1046,6 +1080,11 @@ class Server extends AppModel {
return true;
}
public function testPasswordResetText($value) {
if (strpos($value, '$password') === false || strpos($value, '$username') === false || strpos($value, '$misp') === false) return 'The text served to the users must include the following replacement strings: "$username", "$password", "$misp"';
return true;
}
// never come here directly, always go through a secondary check like testForTermsFile in order to also pass along the expected file path
private function __testForFile($value, $path) {

View File

@ -422,4 +422,105 @@ class User extends AppModel {
));
return $result['User']['gpgkey'];
}
// all e-mail sending is now handled by this method
// Just pass the user ID in an array that is the target of the e-mail along with the message body and the alternate message body if the message cannot be encrypted
// the remaining two parameters are the e-mail subject and a secondary user object which will be used as the replyto address if set. If it is set and an encryption key for the replyTo user exists, then his/her public key will also be attached
public function sendEmail($user, $body, $bodyNoEnc = false, $subject, $replyToUser = false) {
$failed = false;
$failureReason = "";
// check if the e-mail can be encrypted
$canEncrypt = false;
if (isset($user['User']['gpgkey']) && !empty($user['User']['gpgkey'])) $canEncrypt = true;
// If bodyonlencrypted is enabled and the user has no encryption key, use the alternate body (if it exists)
if (Configure::read('GnuPG.bodyonlyencrypted') && !$canEncrypt && $bodyNoEnc) {
$body = $bodyNoEnc;
}
// Sign the body
require_once 'Crypt/GPG.php';
try {
$gpg = new Crypt_GPG(array('homedir' => Configure::read('GnuPG.homedir'))); // , 'debug' => true
$gpg->addSignKey(Configure::read('GnuPG.email'), Configure::read('GnuPG.password'));
$body = $gpg->sign($body, Crypt_GPG::SIGN_MODE_CLEAR);
} catch (Exception $e) {
$failureReason = " the message could not be signed. The following error message was returned by gpg: " . $e->getMessage();
$this->log($e->getMessage());
$failed = true;
}
// If we cannot encrypt the mail and the server settings restricts sending unencrypted messages, return false
if (!$failed && !$canEncrypt && Configure::read('GnuPG.onlyencrypted')) {
$failed = true;
$failureReason = " encrypted messages are enforced and the message could not be encrypted for this user as no valid encryption key was found.";
}
// Let's encrypt the message if we can
if (!$failed && $canEncrypt) {
$keyImportOutput = $gpg->importKey($user['User']['gpgkey']);
try {
$gpg->addEncryptKey($keyImportOutput['fingerprint']); // use the key that was given in the import
$body = $gpg->encrypt($body, true);
} catch (Exception $e){
// despite the user having a PGP key and the signing already succeeding earlier, we get an exception. This must mean that there is an issue with the user's key.
$failureReason = " the message could not be encrypted because there was an issue with the user's PGP key. The following error message was returned by gpg: " . $e->getMessage();
$this->log($e->getMessage());
$failed = true;
}
}
$replyToLog = '';
if (!$failed) {
$Email = new CakeEmail();
// If the e-mail is sent on behalf of a user, then we want the target user to be able to respond to the sender
// For this reason we should also attach the public key of the sender along with the message (if applicable)
if ($replyToUser != false) {
$Email->replyTo($replyToUser['User']['email']);
if (!empty($replyToUser['User']['gpgkey'])) $Email->attachments(array('gpgkey.asc' => array('data' => $replyToUser['User']['gpgkey'])));
$replyToLog = 'from ' . $replyToUser['User']['email'];
}
$Email->from(Configure::read('MISP.email'));
$Email->to($user['User']['email']);
$Email->subject($subject);
$Email->emailFormat('text');
$result = $Email->send($body);
$Email->reset();
}
$this->Log = ClassRegistry::init('Log');
$this->Log->create();
if (!$failed && $result) {
$this->Log->save(array(
'org' => 'SYSTEM',
'model' => 'User',
'model_id' => $user['User']['id'],
'email' => $user['User']['email'],
'action' => 'email',
'title' => 'Email ' . $replyToLog . ' to ' . $user['User']['email'] . ' sent, titled "' . $subject . '".',
'change' => null,
));
return true;
} else {
if (isset($result) && !$result) $failureReason = " there was an error sending the e-mail.";
$this->Log->save(array(
'org' => 'SYSTEM',
'model' => 'User',
'model_id' => $user['User']['id'],
'email' => $user['User']['email'],
'action' => 'email',
'title' => 'Email ' . $replyToLog . ' to ' . $user['User']['email'] . ', titled "' . $subject . '" failed. Reason: ' . $failureReason,
'change' => null,
));
}
return false;
}
public function adminMessageResolve($message) {
$resolveVars = array('$contact' => 'MISP.contact', '$org' => 'MISP.org', '$misp' => 'MISP.baseurl');
foreach ($resolveVars as $k => $v) {
$v = Configure::read($v);
$message = str_replace($k, $v, $message);
}
return $message;
}
}

View File

@ -0,0 +1,273 @@
<?php
/**
* Client SSL Certificate Authentication component
*
* Authorizes users based on their SSL credentials.
*
* Copyright (c) FIRST.Org, Inc. (https://first.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @author Guilherme Capilé, Tecnodesign (https://tecnodz.com)
* @copyright Copyright (c) FIRST.Org, Inc. (https://first.org)
* @link http://github.com/FIRSTdotorg/cakephp-CertAuth
* @package CertAuth.Certificate
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
App::uses('AuthComponent', 'Controller/Component');
App::uses('BaseAuthenticate', 'Controller/Component/Auth');
class CertificateAuthenticate extends BaseAuthenticate
{
/**
* Holds the certificate issuer information (available at SSL_CLIENT_I_DN)
*
* @var array
*/
protected static $ca;
/**
* Holds the certificate user information (available at SSL_CLIENT_S_DN)
*
* @var array
*/
protected static $client;
/**
* Holds the user information
*
* @var array
*/
protected static $user;
/**
* Class constructor.
*
* This should only be called once per request, so it doesn't need to store values in
* the instance. Simply checks if the certificate is valid (against configured valid issuers)
* and returns the user information encoded.
*/
public function __construct()
{
self::$ca = self::$client = false;
// this means the client certificate is valid — check nginx/apache configuration
if(isset($_SERVER['SSL_CLIENT_VERIFY']) && $_SERVER['SSL_CLIENT_VERIFY']=='SUCCESS') {
if(isset($_SERVER['SSL_CLIENT_I_DN'])) {
$CA = self::parse($_SERVER['SSL_CLIENT_I_DN'], Configure::read('CertAuth.mapCa'));
// only valid CAs, if this was configured
if($ca=Configure::read('CertAuth.ca')) {
$k = Configure::read('CertAuth.caId');
if(!$k) $k = 'CN';
$id = (isset($CA[$k]))?($CA[$k]):(false);
if(!$id) {
$CA = false;
} else if(is_array($ca)) {
if(!in_array($id, $ca)) $CA = false;
} else if($ca!=$id) {
$CA = false;
}
unset($id, $k);
}
self::$ca = $CA;
unset($CA, $ca);
}
if(self::$ca && isset($_SERVER['SSL_CLIENT_S_DN'])) {
self::$client = self::parse($_SERVER['SSL_CLIENT_S_DN'], Configure::read('CertAuth.map'));
}
}
}
/**
* Parse certificate extensions
*
* @TODO this should properly address the RFC
* @param string $s text to be parsed
* @param (optional) array $map array of mapping extension to User fields
* @return array parsed values
*/
private static function parse($s, $map=null)
{
$r=array();
foreach(preg_split('#/#', $s, null, PREG_SPLIT_NO_EMPTY) as $v) {
if($p=strpos($v, '=')) {
$k = substr($v, 0, $p);
if($map) {
if(isset($map[$k])) {
$k = $map[$k];
} else {
unset($p, $v, $k);
continue;
}
}
$r[$k] = substr($v, $p+1);
}
unset($p, $v, $k);
}
return $r;
}
// to enable stateless authentication
public function getUser(CakeRequest $request)
{
if(is_null(self::$user)) {
if(self::$client) {
self::$user = self::$client;
$sync = Configure::read('CertAuth.syncUser');
if($sync) {
self::getRestUser();
}
// find and fill user with model
$cn = Configure::read('CertAuth.userModel');
if($cn) {
$k = Configure::read('CertAuth.userModelKey');
if($k) {
$q = array($k=>self::$user[$k]);
} else {
$q = self::$user;
}
$User = ClassRegistry::init($cn);
$U = $User->find('first', array(
'conditions' => $q,
'recursive' => false
));
if($U) {
if($sync) {
$write = array();
foreach(self::$user as $k=>$v) {
if(array_key_exists($k, $U[$cn]) && trim($U[$cn][$k])!=trim($v)) {
$write[] = $k;
$U[$cn][$k] = trim($v);
}
unset($k, $v);
}
if($write && !$User->save($U[$cn], true, $write)) {
CakeLog::write('alert', 'Could not update model at database with RestAPI data.');
}
unset($write);
}
self::$user = $U[$cn];
} else if($sync) {
$User->create();
$d = Configure::read('CertAuth.userDefaults');
if($d && is_array($d)) {
self::$user += $d;
}
unset($d);
if($User->save(self::$user, true, array_keys(self::$user))) {
$U = $User->read();
self::$user = $U[$cn];
} else {
CakeLog::write('alert', 'Could not insert model at database from RestAPI data.');
}
}
unset($U, $User, $q, $k);
}
unset($cn);
}
}
return self::$user;
}
// to enable stateless authentication
public function authenticate(CakeRequest $request, CakeResponse $response)
{
return self::getUser($request);
}
/**
* Fetches user information from external REST API
*
* Valid options (should be configured under CertAuth.restApi):
*
* @param (optional) array $options API configuration
* url (string) Where to fetch information from
* headers (array) list of additional headers to be used, reserved for authentication tokens
* params (array) mapping of additional params to be included at the url, uses $user values
* map (array) mapping of the return values to be added to the self::$user
* @return array updated user object
*/
public function getRestUser($options=null, $user=null)
{
if(is_null($options)) {
$options = Configure::read('CertAuth.restApi');
}
if(!is_null($user)) {
self::$user = $user;
}
if(!isset($options['url'])) {
return null;
}
// Create a stream
$req = array(
'http'=>array(
'method'=>'GET',
'header'=>"Accept: application/json\r\n"
),
);
if(isset($options['headers'])) {
foreach($options['headers'] as $k=>$v) {
if(is_int($k)) {
$req['header'] .= "{$v}\r\n";
} else {
$req['header'] .= "{$k}: {$v}\r\n";
}
unset($k, $v);
}
}
$url = $options['url'];
if(isset($options['param'])) {
foreach($options['param'] as $k=>$v) {
if(isset(self::$user[$v])) {
$url .= ((strpos($url, '?'))?('&'):('?'))
. $k . '=' . urlencode(self::$user[$v]);
}
unset($k, $v);
}
}
$ctx = stream_context_create($req);
$a = file_get_contents($url, false, $ctx);
if(!$a) return null;
$A = json_decode($a, true);
if(!isset($A['data'][0])) return false;
if(isset($options['map'])) {
foreach($options['map'] as $k=>$v) {
if(isset($A['data'][0][$k])) {
self::$user[$v] = $A['data'][0][$k];
}
unset($k, $v);
}
}
return self::$user;
}
protected static $instance;
public static function ca()
{
if(is_null(self::$ca)) new CertificateAuthenticate();
return self::$ca;
}
public static function client()
{
if(is_null(self::$client)) new CertificateAuthenticate();
return self::$client;
}
}

View File

@ -0,0 +1,45 @@
#Client SSL Certificate Authentication for CakePHP
This plugin enables CakePHP applications to use client SSL certificates to stateless authenticate its users. It reads information from the client certificate and can synchronize data with a foreign REST API and the client User model.
Basically it loads the `SSL_CLIENT_*` variables, parses and maps the certificate information to the user. So you first need a server that checks client certificates and forwards that information to the PHP `$_SERVER` environment.
## Usage
Enable the plugin at bootstrap.php:
```php
CakePlugin::load('CertAuth');
```
And configure it:
```php
Configure::write('CertAuth',
array(
'ca' => array( 'FIRST.Org' ), // allowed CAs
'caId' => 'O', // which attribute will be used to verify the CA
'userModel' => 'User', // name of the User class to check if user exists
'userModelKey' => 'nids_sid', // User field that will be used for querying
'map' => array( // maps client certificate attributes to User properties
'O' => 'org',
'emailAddress'=>'email',
),
'syncUser' => true, // should the User be synchronized with an external REST API
'restApi' => array( // API parameters
'url' => 'https://example.com/data/users', // URL to query
'headers' => array(), // additional headers, used for authentication
'param' => array( 'email' => 'email'), // query parameters to add to the URL, mapped to USer properties
'map' => array( // maps REST result to the User properties
'uid' => 'id',
'name' => 'name',
'company' => 'org',
'email' => 'email',
),
),
),
));
```

View File

@ -21,10 +21,10 @@
<td class="short" style="<?php echo $bgColour; ?>"><?php echo h($priorities[$setting['level']]);?></td>
<td class="short" style="<?php echo $bgColour; ?>"><?php echo h($setting['setting']);?></td>
<?php if ((isset($setting['editable']) && !$setting['editable']) || $setting['level'] == 3): ?>
<td id="setting_<?php echo $k; ?>_passive" class="short inline-field-solid" style="<?php echo $bgColour; ?>width:300px;"><?php echo h($setting['value']);?></td>
<td id="setting_<?php echo $k; ?>_passive" class="inline-field-solid" style="<?php echo $bgColour; ?>width:500px;"><?php echo nl2br(h($setting['value']));?></td>
<?php else: ?>
<td id="setting_<?php echo $k; ?>_solid" class="short inline-field-solid" onClick="serverSettingsActivateField('<?php echo $setting['setting'];?>', '<?php echo $k;?>')" style="<?php echo $bgColour; ?>width:300px;"><?php echo h($setting['value']);?></td>
<td id="setting_<?php echo $k; ?>_placeholder" class="short hidden inline-field-placeholder" style="<?php echo $bgColour; ?>width:300px;"></td>
<td id="setting_<?php echo $k; ?>_solid" class="inline-field-solid" ondblclick="serverSettingsActivateField('<?php echo $setting['setting'];?>', '<?php echo $k;?>')" style="<?php echo $bgColour; ?>width:500px;"><?php echo h($setting['value']);?></td>
<td id="setting_<?php echo $k; ?>_placeholder" class="short hidden inline-field-placeholder" style="<?php echo $bgColour; ?>width:500px;"></td>
<?php endif; ?>
<td style="<?php echo $bgColour; ?>"><?php echo h($setting['description']);?></td>
<td style="<?php echo $bgColour; ?>"><?php if (isset($setting['error']) && $setting['level'] != 3) echo h($setting['errorMessage']); ?></td>

View File

@ -131,6 +131,7 @@
case 'admin':
if ($menuItem === 'editUser' || $menuItem === 'viewUser'): ?>
<li <?php if ($menuItem === 'viewUser') echo 'class="active"';?>><?php echo $this->Html->link('View User', array('controller' => 'users', 'action' => 'view', 'admin' => true, $id)); ?> </li>
<li><a href="#/" onClick="initiatePasswordReset('<?php echo h($id); ?>');">Send Credentials</a></li>
<li <?php if ($menuItem === 'editUser') echo 'class="active"';?>><?php echo $this->Html->link('Edit User', array('controller' => 'users', 'action' => 'edit', 'admin' => true, $id)); ?> </li>
<li><?php echo $this->Form->postLink('Delete User', array('admin' => true, 'action' => 'delete', $id), null, __('Are you sure you want to delete # %s?', $id));?></li>
<li class="divider"></li>
@ -143,8 +144,12 @@
if ($isSiteAdmin): ?>
<li <?php if ($menuItem === 'addUser') echo 'class="active"';?>><?php echo $this->Html->link('New User', array('controller' => 'users', 'action' => 'add', 'admin' => true)); ?> </li>
<li <?php if ($menuItem === 'indexUser') echo 'class="active"';?>><?php echo $this->Html->link('List Users', array('controller' => 'users', 'action' => 'index', 'admin' => true)); ?> </li>
<?php endif; ?>
<?php if ($isAdmin): ?>
<li <?php if ($menuItem === 'contact') echo 'class="active"';?>><?php echo $this->Html->link('Contact Users', array('controller' => 'users', 'action' => 'email', 'admin' => true)); ?> </li>
<?php endif; ?>
<li class="divider"></li>
<?php if ($isSiteAdmin): ?>
<li <?php if ($menuItem === 'addRole') echo 'class="active"';?>><?php echo $this->Html->link('New Role', array('controller' => 'roles', 'action' => 'add', 'admin' => true)); ?> </li>
<?php endif; ?>
<li <?php if ($menuItem === 'indexRole') echo 'class="active"';?>><?php echo $this->Html->link('List Roles', array('controller' => 'roles', 'action' => 'index', 'admin' => true)); ?> </li>

View File

@ -1,31 +1,45 @@
<?php
/**
*
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package Cake.View.Errors
* @package app.View.Errors
* @since CakePHP(tm) v 0.10.0.1076
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
?>
<h2><?php echo $name; ?></h2>
<p class="error">
<strong><?php echo __d('cake', 'Error'); ?>: </strong>
<?php printf(
__d('cake', 'The requested address %s was not found on this server.'),
"<strong>'{$url}'</strong>"
); ?>
</p>
<?php
if (Configure::read('debug') > 0 ):
echo $this->element('exception_stack_trace');
endif;
?>
if ($message !== 'csrf'):
?>
<h2><?php echo $message; ?></h2>
<p class="error">
<strong><?php echo __d('cake', 'Error'); ?>: </strong>
<?php printf(
__d('cake', 'The requested address %s was not found on this server.'),
"<strong>'{$url}'</strong>"
); ?>
</p>
<?php
if (Configure::read('debug') > 0):
echo $this->element('exception_stack_trace');
endif;
else:
?>
<h2>You have tripped the cross-site request forgery protection of MISP</h2>
<p class="error">
<strong>CSRF error:</strong>
This happens usually when you try to resubmit the same form with invalidated CSRF tokens or you had a form open too long and the CSRF tokens simply expired. Just go back to the previous page and refresh the form (by reloading the same url) so that the tokens get refreshed.
</p>
<p>
Alternatively, click <a href="/">here</a> to continue to the start page.
</p>
<?php
if (Configure::read('debug') > 0):
echo $this->element('exception_stack_trace');
endif;
endif;

View File

@ -25,8 +25,10 @@
'div' => false
));
} else {
$type = 'text';
if (isset($setting['bigField'])) $type = 'textarea';
echo $this->Form->input('value', array(
'type' => 'text',
'type' => $type,
'label' => false,
'value' => $setting['value'],
'error' => array('escape' => false),

View File

@ -13,6 +13,9 @@
echo $this->Form->input('authkey', array('value' => $authkey, 'readonly' => 'readonly'));
echo $this->Form->input('nids_sid');
echo $this->Form->input('gpgkey', array('label' => 'GPG key', 'div' => 'clear', 'class' => 'input-xxlarge'));
?>
<div class="clear"><span onClick="lookupPGPKey('UserEmail');" class="btn btn-inverse" style="margin-bottom:10px;">Fetch GPG key</span></div>
<?php
echo $this->Form->input('autoalert', array('label' => 'Receive alerts when events are published'));
echo $this->Form->input('contactalert', array('label' => 'Receive alerts from "contact reporter" requests'));

View File

@ -18,6 +18,9 @@
'class' => 'datepicker',
));
echo $this->Form->input('gpgkey', array('label' => 'GPG key', 'div' => 'clear', 'class' => 'input-xxlarge'));
?>
<div class="clear"><span onClick="lookupPGPKey('UserEmail');" class="btn btn-inverse" style="margin-bottom:10px;">Fetch GPG key</span></div>
<?php
echo $this->Form->input('termsaccepted', array('label' => 'Terms accepted'));
echo $this->Form->input('change_pw', array('type' => 'checkbox', 'label' => 'Change Password'));
echo $this->Form->input('autoalert', array('label' => 'Receive alerts when events are published'));

View File

@ -1,8 +1,3 @@
<script>
function showMessage(){
document.getElementById("messageDiv").style.display="none"){
}
</script>
<div class="events form">
<?php echo $this->Form->create('User');?>
<fieldset>
@ -19,8 +14,8 @@ function showMessage(){
</ul>
<?php
// This choice will determine
$actionOptions=array('Custom message', 'Send temporary password');
$recipientOptions=array('All existing users', 'An existing user', 'New user');
$actionOptions=array('Custom message', 'Welcome message', 'Reset password');
$recipientOptions=array('A single user', 'All users');
?>
<div class="row-fluid">
<?php echo $this->Form->input('action', array('type' => 'select', 'options' => $actionOptions, 'id' => 'action')); ?>
@ -30,31 +25,25 @@ function showMessage(){
</div>
<div class="row-fluid">
<?php echo $this->Form->input('recipient', array('type' => 'select', 'options' => $recipientOptions, 'id' => 'recipient')); ?>
<div id="recipientEmail">
<?php echo $this->Form->input('recipientEmail', array('type' => 'text', 'label' => 'Recipient Email', 'style' => 'width:300px;')); ?>
</div>
<div id="recipientEmailList">
<div id="recipientEmailList" class="hideAble">
<?php echo $this->Form->input('recipientEmailList', array('type' => 'select', 'options' => $recipientEmail, 'label' => 'Recipient Email')); ?>
</div>
</div>
<div id="gpg" class="row-fluid">
<?php echo $this->Form->input('gpg', array('type' => 'textarea', 'class' => 'input-xxlarge')); ?>
</div>
<div id="customMessage" class="row-fluid">
<div id="customMessage" class="row-fluid hideAble">
<?php
echo $this->Form->input('customMessage', array(
'label' => __('Enter a custom message', true),
'type' => 'checkbox',
'checked' => 'checked',
'id' => 'customMessageToggle'
));
?>
</div>
<div class="row-fluid">
<?php
$str=$this->Form->input('message', array('type' => 'textarea', 'class' => 'input-xxlarge'));
echo $this->Html->div('messageDiv', $str, array('id' => 'messageDiv'));
?>
<div id="messageDiv" class="messageDiv hideAble">
<?php
echo $this->Form->input('message', array('type' => 'textarea', 'class' => 'input-xxlarge'));
?>
</div>
</div>
<div class="row-fluid">
<?php
@ -68,56 +57,31 @@ function showMessage(){
echo $this->element('side_menu', array('menuList' => 'admin', 'menuItem' => 'contact'));
?>
<script>
$("#recipient").change(setRecipientEmailList);
$("#recipient").change(setGPG);
$("#action").change(setMessage);
$("#customMessage").change(setMessage2);
$(document).ready(setRecipientEmailList);
$(document).ready(setGPG);
$(document).ready(setMessage);
$("#recipient").change(setAll);
$("#action").change(setAll);
$("#customMessage").change(setAll);
$("#action").change(populateSubject);
var subjects = [];
var standardTexts = [];
$(document).ready(function() {
var org = "<?php echo $org;?>";
subjects = ["", "[" + org + " MISP] New user registration", "[" + org + " MISP] Password reset"];
standardTexts = ['', '<?php echo h($newUserText); ?>', '<?php echo h($passwordResetText); ?>'];
//setAll();
});
function setRecipientEmailList() {
if ($("#recipient option:selected").text() == "An existing user") {
document.getElementById("recipientEmailList").style.display="";
document.getElementById("recipientEmail").style.display="none";
} else if ($("#recipient option:selected").text() == "All existing users") {
document.getElementById("recipientEmailList").style.display="none";
document.getElementById("recipientEmail").style.display="none";
} else if ($("#recipient option:selected").text() == "New user") {
document.getElementById("recipientEmailList").style.display="none";
document.getElementById("recipientEmail").style.display="";
}
function populateSubject() {
$("#UserSubject").val(subjects[$("#action").val()]);
$("#UserMessage").html(standardTexts[$("#action").val()]).text();
}
function setMessage() {
if ($("#action option:selected").text() == "Custom message") {
document.getElementById("customMessage").style.display="none";
document.getElementById("messageDiv").style.display="";
document.getElementById("subject").style.display="";
} else {
document.getElementById("customMessage").style.display="";
document.getElementById("subject").style.display="none";
setMessage2();
}
function setAll() {
$(".hideAble").hide();
if ($("#action option:selected").val() == 0 || $("#customMessageToggle").prop('checked')) $("#messageDiv").show();
if ($("#action option:selected").val() == 0) $("#subject").show();
else $("#customMessage").show();
if ($("#recipient option:selected").val() == 0) $("#recipientEmailList").show();
}
function setMessage2() {
if ($("#customMessageToggle").prop('checked')) {
document.getElementById("messageDiv").style.display="";
} else {
document.getElementById("messageDiv").style.display="none";
}
}
function setGPG(){
if ($("#recipient option:selected").text() == "New user") {
document.getElementById("gpg").style.display="";
} else {
document.getElementById("gpg").style.display="none";
}
}
</script>

View File

@ -84,6 +84,9 @@ foreach ($users as $user): ?>
<td class="short action-links">
<?php
if (($isAclAdmin && (($user['User']['org'] == $me['org'])) || ('1' == $me['id'])) || ($isSiteAdmin)) {
?>
<span class="icon-refresh useCursorPointer" onClick="initiatePasswordReset('<?php echo $user['User']['id']; ?>');"></span>
<?php
echo $this->Html->link('', array('admin' => true, 'action' => 'edit', $user['User']['id']), array('class' => 'icon-edit', 'title' => 'Edit'));
echo $this->Form->postLink('', array('admin' => true, 'action' => 'delete', $user['User']['id']), array('class' => 'icon-trash', 'title' => 'Delete'), __('Are you sure you want to delete # %s?', $user['User']['id']));
}?>

View File

@ -0,0 +1,26 @@
<div class="confirmation">
<?php
$legend = ($firstTime ? 'Send welcome message to user' : 'Initiate password reset for user');
$message = ($firstTime ? 'Are you sure you want to reset the password of ' . $user['User']['email'] . ' and send him/her a welcome message with the credentials?' : 'Are you sure you want to reset the password of ' . $user['User']['email'] . ' and send him/her the temporary credentials? ');
?>
<legend><?php echo $legend; ?></legend>
<div style="padding-left:5px;padding-right:5px;padding-bottom:5px;">
<p><?php echo $message; ?><br /><input id ="firstTime" type="checkbox" style="margin:0px;">First time registration</p>
<table>
<tr>
<td style="vertical-align:top">
<span id="PromptYesButton" class="btn btn-primary" onClick="submitPasswordReset('<?php echo $user['User']['id']; ?>');">Yes</span>
</td>
<td style="width:540px;">
</td>
<td style="vertical-align:top;">
<span class="btn btn-inverse" id="PromptNoButton" onClick="cancelPrompt();">No</span>
</td>
</tr>
</table>
</div>
<?php
echo $this->Form->create('User', array('style' => 'margin:0px;', 'id' => 'PromptForm'));
echo $this->Form->end();
?>
</div>

View File

@ -12,6 +12,9 @@
else echo $this->Form->input('role_id', array('disabled' => 'disabled')); // TODO ACL, check, My Profile not edit role_id.
echo $this->Form->input('nids_sid');
echo $this->Form->input('gpgkey', array('label' => 'GPG key', 'div' => 'clear', 'class' => 'input-xxlarge'));
?>
<div class="clear"><span onClick="lookupPGPKey('UserEmail');" class="btn btn-inverse" style="margin-bottom:10px;">Fetch GPG key</span></div>
<?php
echo $this->Form->input('autoalert', array('label' => 'Receive alerts when events are published'));
echo $this->Form->input('contactalert', array('label' => 'Receive alerts from "contact reporter" requests'));
?>

View File

@ -63,6 +63,37 @@ function submitDeletion(context_id, action, type, id) {
});
}
function initiatePasswordReset(id) {
$.get( "/users/initiatePasswordReset/" + id, function(data) {
$("#confirmation_box").fadeIn();
$("#gray_out").fadeIn();
$("#confirmation_box").html(data);
});
}
function submitPasswordReset(id) {
var formData = $('#PromptForm').serialize();
var url = "/users/initiatePasswordReset/" + id;
if ($('#firstTime').is(":checked")) url += "/true";
$.ajax({
beforeSend: function (XMLHttpRequest) {
$(".loading").show();
},
data: formData,
success:function (data, textStatus) {
handleGenericAjaxResponse(data);
},
complete:function() {
$(".loading").hide();
$("#confirmation_box").fadeOut();
$("#gray_out").fadeOut();
},
type:"post",
cache: false,
url:url,
});
}
function acceptObject(type, id, event) {
name = '#ShadowAttribute_' + id + '_accept';
var formData = $(name).serialize();
@ -287,6 +318,7 @@ function handleAjaxEditResponse(data, name, type, id, field, event) {
}
function handleGenericAjaxResponse(data) {
console.log(data);
if (typeof data == 'string') {
responseArray = JSON.parse(data);
} else {
@ -1350,3 +1382,18 @@ function freetextImportResultsSubmit(id, count) {
},
});
}
function lookupPGPKey(emailFieldName) {
$.ajax({
type: "get",
url: "https://pgp.mit.edu/pks/lookup?op=get&search=" + $('#' + emailFieldName).val(),
success: function (data) {
var result = $("<div>").html(data)[0].getElementsByTagName("pre")[0]['innerText'];
$("#UserGpgkey").val(result);
showMessage('success', "Key found!");
},
error: function (data, textStatus, errorThrown) {
showMessage('fail', textStatus + ": " + errorThrown);
}
});
}