wsattacker.sso.openid.attacker.evaluation.report.SvgOutput.java Source code

Java tutorial

Introduction

Here is the source code for wsattacker.sso.openid.attacker.evaluation.report.SvgOutput.java

Source

/*
 * OpenID Attacker
 * (C) 2015 Christian Mainka & Christian Komann
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 2 of the License, or (at your option) any later
 * version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc., 51
 * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */
package wsattacker.sso.openid.attacker.evaluation.report;

import java.awt.Color;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.io.FileUtils;
import wsattacker.sso.openid.attacker.log.RequestLogEntry;
import wsattacker.sso.openid.attacker.server.IdpType;

public class SvgOutput {
    private static SvgOutput INSTANCE;

    // some predefined positions
    private final int START_Y = 50;
    private final int CLIENT_X = 30;
    private final int SP_X = 230;
    private final int ATTACKER_IDP_X = 430;
    private final int ANALYER_IDP_X = 630;
    private final int DEFAULT_VERTICAL_SPACING = 25;
    private final int DEFAULT_STROKE_WIDTH = 1;
    private final int DEFAULT_FONT_SIZE = 12;
    private final Color DEFAULT_TEXT_COLOR = new Color(0, 137, 197);

    enum Direction {
        LEFT, RIGHT
    }

    private SvgOutput() {

    }

    public static SvgOutput getSvgOutput() {
        if (INSTANCE == null) {
            INSTANCE = new SvgOutput();
        }

        return INSTANCE;
    }

    public String generateAttackOverviewFromLog(List<RequestLogEntry> logEntries) {
        String svgContent = "";
        int currentY = START_Y;

        // Login Request (horizontal arrow from client to SP)
        svgContent += drawHorizontalLineWithArrow(CLIENT_X, SP_X, currentY, Color.BLACK, DEFAULT_STROKE_WIDTH);
        svgContent += drawText((SP_X - CLIENT_X) / 2 + CLIENT_X, currentY - 5, DEFAULT_FONT_SIZE,
                DEFAULT_TEXT_COLOR, "Login Request");
        currentY += 25;

        for (RequestLogEntry entry : logEntries) {
            int idpX = entry.getIdpType() == IdpType.ATTACKER ? ATTACKER_IDP_X : ANALYER_IDP_X;

            switch (entry.getType()) {
            case HTML:
                // HTML Discovery (horizontal arrow from SP to IdP)
                svgContent += drawHorizontalLineWithArrow(SP_X, idpX, currentY, Color.BLACK, DEFAULT_STROKE_WIDTH);
                svgContent += drawText((idpX - SP_X) / 2 + SP_X, currentY - 5, DEFAULT_FONT_SIZE,
                        DEFAULT_TEXT_COLOR, "HTML Discovery");
                break;
            case XRDS:
                // XRDS Discovery (horizontal arrow from SP to IdP)
                svgContent += drawHorizontalLineWithArrow(SP_X, idpX, currentY, Color.BLACK, DEFAULT_STROKE_WIDTH);
                svgContent += drawText((idpX - SP_X) / 2 + SP_X, currentY - 5, DEFAULT_FONT_SIZE,
                        DEFAULT_TEXT_COLOR, "XRDS Discovery");
                break;
            case ASSOCIATION:
                // Association (horizontal line from SP to IdP - arrows on both sides)
                svgContent += drawHorizontalLineWithArrowOnBothSides(SP_X, idpX, currentY, Color.BLACK,
                        DEFAULT_STROKE_WIDTH);
                svgContent += drawText((idpX - SP_X) / 2 + SP_X, currentY - 5, DEFAULT_FONT_SIZE,
                        DEFAULT_TEXT_COLOR, "Association");
                break;
            case TOKEN_ATTACK:
            case TOKEN_VALID:
                // Authentication Request (horizontal arrow from SP to client, then, to IdP)
                svgContent += drawHorizontalLineWithArrow(SP_X, CLIENT_X, currentY, Color.BLACK,
                        DEFAULT_STROKE_WIDTH);
                svgContent += drawText((SP_X - CLIENT_X) / 2 + CLIENT_X, currentY - 5, DEFAULT_FONT_SIZE,
                        DEFAULT_TEXT_COLOR, "Authentication Request");
                svgContent += String.format(
                        "<path d=\"M %d %d a 8 8 0 1 0 0 %d\" fill=\"transparent\" stroke=\"black\" stroke-width=\"1\" />",
                        CLIENT_X, currentY, (int) (DEFAULT_VERTICAL_SPACING * 0.67));
                currentY += DEFAULT_VERTICAL_SPACING * 0.67;
                svgContent += drawHorizontalLineWithArrow(CLIENT_X, idpX, currentY, Color.BLACK,
                        DEFAULT_STROKE_WIDTH);

                currentY += DEFAULT_VERTICAL_SPACING;

                // Authentication Response (horizontal arrow from IdP to client, then, to SP)
                svgContent += drawHorizontalLineWithArrow(idpX, CLIENT_X, currentY, Color.BLACK,
                        DEFAULT_STROKE_WIDTH);
                svgContent += drawText((idpX - CLIENT_X) / 2 + CLIENT_X, currentY - 5, DEFAULT_FONT_SIZE,
                        DEFAULT_TEXT_COLOR, "Authentication Response");
                svgContent += String.format(
                        "<path d=\"M %d %d a 8 8 0 1 0 0 %d\" fill=\"transparent\" stroke=\"black\" stroke-width=\"1\" />",
                        CLIENT_X, currentY, (int) (DEFAULT_VERTICAL_SPACING * 0.67));
                currentY += DEFAULT_VERTICAL_SPACING * 0.67;
                svgContent += drawHorizontalLineWithArrow(CLIENT_X, SP_X, currentY, Color.BLACK,
                        DEFAULT_STROKE_WIDTH);
                break;
            case XXE:
                // XXE (horizontal arrow from SP to IdP)
                svgContent += drawHorizontalLineWithArrow(SP_X, idpX, currentY, Color.BLACK, DEFAULT_STROKE_WIDTH);
                svgContent += drawText((idpX - SP_X) / 2 + SP_X, currentY - 5, DEFAULT_FONT_SIZE,
                        DEFAULT_TEXT_COLOR, "XXE");
                break;
            case CHECK_AUTHENTICATION:
                // Check Authentication (horizontal arrow from SP to IdP)
                svgContent += drawHorizontalLineWithArrow(SP_X, idpX, currentY, Color.BLACK, DEFAULT_STROKE_WIDTH);
                svgContent += drawText((idpX - SP_X) / 2 + SP_X, currentY - 5, DEFAULT_FONT_SIZE,
                        DEFAULT_TEXT_COLOR, "Direct Verification");
                break;
            }

            currentY += 25;
        }

        // success? (horizontal arrow from SP to client)
        svgContent += drawHorizontalLineWithArrow(SP_X, CLIENT_X, currentY, Color.BLACK, DEFAULT_STROKE_WIDTH);
        svgContent += drawText((SP_X - CLIENT_X) / 2 + CLIENT_X, currentY - 5, DEFAULT_FONT_SIZE,
                DEFAULT_TEXT_COLOR, "success?");

        String svgDocument = "";

        try {
            // read from file and replace $svgContent           
            InputStream inputStream = SvgOutput.class.getResourceAsStream("/attack.svg");
            File svgTemplateFile = new File("attack.svg");
            FileUtils.copyInputStreamToFile(inputStream, svgTemplateFile);
            svgDocument = FileUtils.readFileToString(svgTemplateFile);
            svgDocument = svgDocument.replace("$verticalLength", String.format("%d", currentY + 20));
            svgDocument = svgDocument.replace("$svgContent", svgContent);
            svgTemplateFile.delete();
        } catch (IOException ex) {
            Logger.getLogger(HtmlOutput.class.getName()).log(Level.SEVERE, null, ex);
        }

        return svgDocument;
    }

    private String drawText(int x, int y, int fontSize, Color color, String text) {
        return String.format(
                "\t<text x=\"%d\" y=\"%d\" font-size=\"%d\" text-anchor=\"middle\" fill=\"%s\">%s</text>\n", x, y,
                fontSize, colorToHex(color), text);
    }

    private String drawLine(int x1, int y1, int x2, int y2, Color color, int strokeWidth) {
        return String.format(
                "\t<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\" stroke=\"%s\" fill=\"transparent\" stroke-width=\"%d\" />\n",
                x1, y1, x2, y2, colorToHex(color), strokeWidth);
    }

    private String drawHorizontalLineWithArrow(int x1, int x2, int y, Color color, int StrokeWidth) {
        String resultString = "";

        resultString += drawHorizontalLine(x1, x2, y, color, StrokeWidth);

        if (x2 > x1) {
            resultString += drawRightArrow(x2, y);
        } else {
            resultString += drawLeftArrow(x2, y);
        }

        return resultString;
    }

    private String drawHorizontalLineWithArrowOnBothSides(int x1, int x2, int y, Color color, int StrokeWidth) {
        String resultString = "";

        resultString += drawHorizontalLine(x1, x2, y, color, StrokeWidth);

        if (x2 > x1) {
            resultString += drawRightArrow(x2, y);
            resultString += drawLeftArrow(x1, y);
        } else {
            resultString += drawRightArrow(x1, y);
            resultString += drawLeftArrow(x2, y);
        }

        return resultString;
    }

    private String drawHorizontalLine(int x1, int x2, int y, Color color, int StrokeWidth) {
        return drawLine(x1, y, x2, y, color, StrokeWidth);
    }

    private String drawRightArrow(int x, int y) {
        return drawArrow(x, y, Direction.RIGHT);
    }

    private String drawLeftArrow(int x, int y) {
        return drawArrow(x, y, Direction.LEFT);
    }

    private String drawArrow(int x, int y, Direction direction) {
        if (direction == Direction.RIGHT) {
            return String.format("<polygon points=\"%d %d, %d %d, %d %d\" />", x, y, x - 7, y - 4, x - 7, y + 4);
        } else {
            return String.format("<polygon points=\"%d %d, %d %d, %d %d\" />", x, y, x + 7, y - 4, x + 7, y + 4);
        }
    }

    private String colorToHex(Color color) {
        return String.format("#%02x%02x%02x", color.getRed(), color.getGreen(), color.getBlue());
    }
}