View Javadoc
1   /*
2    * Cloudformation Plugin for SonarQube
3    * Copyright (C) 2019 James Pether Sörling
4    * james@hack23.com
5    *
6    * This program is free software; you can redistribute it and/or
7    * modify it under the terms of the GNU Lesser General Public
8    * License as published by the Free Software Foundation; either
9    * version 3 of the License, or (at your option) any later version.
10   *
11   * This program is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14   * Lesser General Public License for more details.
15   *
16   * You should have received a copy of the GNU Lesser General Public License
17   * along with this program; if not, write to the Free Software Foundation,
18   * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19   */
20  package com.hack23.sonar.cloudformation;
21  
22  import java.io.InputStream;
23  import java.io.InputStreamReader;
24  import java.nio.charset.StandardCharsets;
25  import java.util.Set;
26  
27  import org.apache.commons.lang3.reflect.FieldUtils;
28  import org.sonar.api.server.rule.RulesDefinition;
29  import org.sonar.api.server.rule.RulesDefinitionXmlLoader;
30  import org.sonar.api.utils.log.Logger;
31  import org.sonar.api.utils.log.Loggers;
32  
33  /**
34   * The Class CloudformationRulesDefinition.
35   */
36  public final class CloudformationRulesDefinition implements RulesDefinition {
37  
38  	/** The Constant LOGGER. */
39  	private static final Logger LOGGER = Loggers.get(CloudformationRulesDefinition.class);
40  
41  	/** The Constant PATH_TO_RULES_XML. */
42  	private static final String PATH_TO_RULES_XML = "/cloudformation-rules.xml";
43  
44  	/** The Constant PATH_TO_CHECKOV_CLOUDFORMATION_RULES_XML. */
45  	private static final String PATH_TO_CHECKOV_CLOUDFORMATION_RULES_XML = "/cloudformation-checkov-cloudformation-rules.xml";
46  
47  	/** The Constant PATH_TO_CHECKOV_TERRAFOM_RULES_XML. */
48  	private static final String PATH_TO_CHECKOV_TERRAFOM_RULES_XML = "/cloudformation-checkov-terraform-rules.xml";
49  
50  
51  	/** The Constant KEY. */
52  	public static final String KEY = "repo";
53  
54  	/** The Constant NAME. */
55  	public static final String NAME = "repository";
56  
57  	/** The context. */
58  	private Context context;
59  
60  	/** The xml loader. */
61  	private final RulesDefinitionXmlLoader xmlLoader;
62  
63  	/**
64  	 * Instantiates a new cloudformation rules definition.
65  	 *
66  	 * @param xmlLoader the xml loader
67  	 */
68  	public CloudformationRulesDefinition(final RulesDefinitionXmlLoader xmlLoader) {
69  		super();
70  		this.xmlLoader = xmlLoader;
71  	}
72  
73  	/**
74  	 * Gets the context.
75  	 *
76  	 * @return the context
77  	 */
78  	public Context getContext() {
79  		return context;
80  	}
81  
82  	/**
83  	 * Define rules for cloudformation.
84  	 *
85  	 * @param context the context
86  	 * @param repositoryKey the repository key
87  	 * @param repositoryName the repository name
88  	 * @param languageKey the language key
89  	 */
90  	private void defineRulesForCloudformation(final Context context, final String repositoryKey, final String repositoryName,
91  			final String languageKey) {
92  		final NewRepository repository = context.createRepository(repositoryKey, languageKey).setName(repositoryName);
93  
94  		addRules(repository, this.getClass().getResourceAsStream(PATH_TO_RULES_XML));
95  		addRules(repository, this.getClass().getResourceAsStream(PATH_TO_CHECKOV_CLOUDFORMATION_RULES_XML));
96  		repository.done();
97  	}
98  
99  
100 	/**
101 	 * Define rules for terraform.
102 	 *
103 	 * @param context the context
104 	 * @param repositoryKey the repository key
105 	 * @param repositoryName the repository name
106 	 * @param languageKey the language key
107 	 */
108 	private void defineRulesForTerraform(final Context context, final String repositoryKey, final String repositoryName,
109 			final String languageKey) {
110 		final NewRepository repository = context.createRepository(repositoryKey, languageKey).setName(repositoryName);
111 		addRules(repository, this.getClass().getResourceAsStream(PATH_TO_CHECKOV_TERRAFOM_RULES_XML));
112 		repository.done();
113 	}
114 
115 
116 	/**
117 	 * Adds the rules.
118 	 *
119 	 * @param repository the repository
120 	 * @param rulesXml the rules xml
121 	 */
122 	private void addRules(final NewRepository repository, final InputStream rulesXml) {
123 		if (rulesXml != null) {
124 			xmlLoader.load(repository, new InputStreamReader(rulesXml,StandardCharsets.UTF_8));
125 			for (final NewRule newRule : repository.rules()) {
126 				addNewRule(newRule);
127 			}
128 		}
129 	}
130 
131 	/**
132 	 * Adds the new rule.
133 	 *
134 	 * @param newRule the new rule
135 	 */
136 	private static void addNewRule(final NewRule newRule) {
137 		try {
138 			final Set<String> tags = (Set<String>) FieldUtils.readField(newRule, "tags", true);
139 			for (final String tag : tags) {
140 
141 				if (tag.contains("cweid-")) {
142 					newRule.addCwe(Integer.parseInt(tag.replace("cweid-", "")));
143 				}
144 
145 				if (tag.contains("owasp-")) {
146 					newRule.addOwaspTop10(OwaspTop10.valueOf(tag.replace("owasp-", "").toUpperCase()));
147 				}
148 			}
149 		} catch (final IllegalAccessException e) {
150 			LOGGER.warn("Problem parsing security tags", e);
151 		}
152 	}
153 
154 	/**
155 	 * Define.
156 	 *
157 	 * @param context the context
158 	 */
159 	@Override
160 	public void define(final Context context) {
161 		this.context = context;
162 		defineRulesForCloudformation(context, "cloudformation-plugin-cfn" ,"Cloudformation plugin(cfn) rules", "cloudformation");
163 		defineRulesForTerraform(context, "cloudformation-plugin-terraform" ,"Cloudformation plugin(terrraform) Rules", "terraform");
164 	}
165 
166 }