1 module soup.HSTSEnforcer;
2 
3 private import glib.ConstructionException;
4 private import glib.ListG;
5 private import glib.Str;
6 private import gobject.ObjectG;
7 private import gobject.Signals;
8 private import soup.HSTSPolicy;
9 private import soup.Message;
10 private import soup.SessionFeatureIF;
11 private import soup.SessionFeatureT;
12 private import soup.c.functions;
13 public  import soup.c.types;
14 private import std.algorithm;
15 
16 
17 /**
18  * A #SoupHSTSEnforcer stores HSTS policies and enforces them when
19  * required. #SoupHSTSEnforcer implements #SoupSessionFeature, so you
20  * can add an HSTS enforcer to a session with
21  * soup_session_add_feature() or soup_session_add_feature_by_type().
22  * 
23  * #SoupHSTSEnforcer keeps track of all the HTTPS destinations that,
24  * when connected to, return the Strict-Transport-Security header with
25  * valid values. #SoupHSTSEnforcer will forget those destinations
26  * upon expiry or when the server requests it.
27  * 
28  * When the #SoupSession the #SoupHSTSEnforcer is attached to queues
29  * or restarts a message, the #SoupHSTSEnforcer will rewrite the URI
30  * to HTTPS if the destination is a known HSTS host and is contacted
31  * over an insecure transport protocol (HTTP). Users of
32  * #SoupHSTSEnforcer are advised to listen to changes in
33  * SoupMessage:uri in order to be aware of changes in the message URI.
34  * 
35  * Note that #SoupHSTSEnforcer does not support any form of long-term
36  * HSTS policy persistence. See #SoupHSTSDBEnforcer for a persistent
37  * enforcer.
38  */
39 public class HSTSEnforcer : ObjectG, SessionFeatureIF
40 {
41 	/** the main Gtk struct */
42 	protected SoupHSTSEnforcer* soupHSTSEnforcer;
43 
44 	/** Get the main Gtk struct */
45 	public SoupHSTSEnforcer* getHSTSEnforcerStruct(bool transferOwnership = false)
46 	{
47 		if (transferOwnership)
48 			ownedRef = false;
49 		return soupHSTSEnforcer;
50 	}
51 
52 	/** the main Gtk struct as a void* */
53 	protected override void* getStruct()
54 	{
55 		return cast(void*)soupHSTSEnforcer;
56 	}
57 
58 	/**
59 	 * Sets our main struct and passes it to the parent class.
60 	 */
61 	public this (SoupHSTSEnforcer* soupHSTSEnforcer, bool ownedRef = false)
62 	{
63 		this.soupHSTSEnforcer = soupHSTSEnforcer;
64 		super(cast(GObject*)soupHSTSEnforcer, ownedRef);
65 	}
66 
67 	// add the SessionFeature capabilities
68 	mixin SessionFeatureT!(SoupHSTSEnforcer);
69 
70 
71 	/** */
72 	public static GType getType()
73 	{
74 		return soup_hsts_enforcer_get_type();
75 	}
76 
77 	/**
78 	 * Creates a new #SoupHSTSEnforcer. The base #SoupHSTSEnforcer class
79 	 * does not support persistent storage of HSTS policies, see
80 	 * #SoupHSTSEnforcerDB for that.
81 	 *
82 	 * Returns: a new #SoupHSTSEnforcer
83 	 *
84 	 * Since: 2.68
85 	 *
86 	 * Throws: ConstructionException GTK+ fails to create the object.
87 	 */
88 	public this()
89 	{
90 		auto __p = soup_hsts_enforcer_new();
91 
92 		if(__p is null)
93 		{
94 			throw new ConstructionException("null returned by new");
95 		}
96 
97 		this(cast(SoupHSTSEnforcer*) __p, true);
98 	}
99 
100 	/**
101 	 * Gets a list of domains for which there are policies in @enforcer.
102 	 *
103 	 * Params:
104 	 *     sessionPolicies = whether to include session policies
105 	 *
106 	 * Returns: a newly allocated
107 	 *     list of domains. Use g_list_free_full() and g_free() to free the
108 	 *     list.
109 	 *
110 	 * Since: 2.68
111 	 */
112 	public ListG getDomains(bool sessionPolicies)
113 	{
114 		auto __p = soup_hsts_enforcer_get_domains(soupHSTSEnforcer, sessionPolicies);
115 
116 		if(__p is null)
117 		{
118 			return null;
119 		}
120 
121 		return new ListG(cast(GList*) __p, true);
122 	}
123 
124 	/**
125 	 * Gets a list with the policies in @enforcer.
126 	 *
127 	 * Params:
128 	 *     sessionPolicies = whether to include session policies
129 	 *
130 	 * Returns: a newly
131 	 *     allocated list of policies. Use g_list_free_full() and
132 	 *     soup_hsts_policy_free() to free the list.
133 	 *
134 	 * Since: 2.68
135 	 */
136 	public ListG getPolicies(bool sessionPolicies)
137 	{
138 		auto __p = soup_hsts_enforcer_get_policies(soupHSTSEnforcer, sessionPolicies);
139 
140 		if(__p is null)
141 		{
142 			return null;
143 		}
144 
145 		return new ListG(cast(GList*) __p, true);
146 	}
147 
148 	/**
149 	 * Gets whether @hsts_enforcer has a currently valid policy for @domain.
150 	 *
151 	 * Params:
152 	 *     domain = a domain.
153 	 *
154 	 * Returns: %TRUE if access to @domain should happen over HTTPS, false
155 	 *     otherwise.
156 	 *
157 	 * Since: 2.68
158 	 */
159 	public bool hasValidPolicy(string domain)
160 	{
161 		return soup_hsts_enforcer_has_valid_policy(soupHSTSEnforcer, Str.toStringz(domain)) != 0;
162 	}
163 
164 	/**
165 	 * Gets whether @hsts_enforcer stores policies persistenly.
166 	 *
167 	 * Returns: %TRUE if @hsts_enforcer storage is persistent or %FALSE otherwise.
168 	 *
169 	 * Since: 2.68
170 	 */
171 	public bool isPersistent()
172 	{
173 		return soup_hsts_enforcer_is_persistent(soupHSTSEnforcer) != 0;
174 	}
175 
176 	/**
177 	 * Sets @policy to @hsts_enforcer. If @policy is expired, any
178 	 * existing HSTS policy for its host will be removed instead. If a
179 	 * policy existed for this host, it will be replaced. Otherwise, the
180 	 * new policy will be inserted. If the policy is a session policy, that
181 	 * is, one created with soup_hsts_policy_new_session_policy(), the policy
182 	 * will not expire and will be enforced during the lifetime of
183 	 * @hsts_enforcer's #SoupSession.
184 	 *
185 	 * Params:
186 	 *     policy = the policy of the HSTS host
187 	 *
188 	 * Since: 2.68
189 	 */
190 	public void setPolicy(HSTSPolicy policy)
191 	{
192 		soup_hsts_enforcer_set_policy(soupHSTSEnforcer, (policy is null) ? null : policy.getHSTSPolicyStruct());
193 	}
194 
195 	/**
196 	 * Sets a session policy for @domain. A session policy is a policy
197 	 * that is permanent to the lifetime of @hsts_enforcer's #SoupSession
198 	 * and doesn't expire.
199 	 *
200 	 * Params:
201 	 *     domain = policy domain or hostname
202 	 *     includeSubdomains = %TRUE if the policy applies on sub domains
203 	 *
204 	 * Since: 2.68
205 	 */
206 	public void setSessionPolicy(string domain, bool includeSubdomains)
207 	{
208 		soup_hsts_enforcer_set_session_policy(soupHSTSEnforcer, Str.toStringz(domain), includeSubdomains);
209 	}
210 
211 	/**
212 	 * Emitted when @hsts_enforcer changes. If a policy has been added,
213 	 * @new_policy will contain the newly-added policy and
214 	 * @old_policy will be %NULL. If a policy has been deleted,
215 	 * @old_policy will contain the to-be-deleted policy and
216 	 * @new_policy will be %NULL. If a policy has been changed,
217 	 * @old_policy will contain its old value, and @new_policy its
218 	 * new value.
219 	 *
220 	 * Note that you shouldn't modify the policies from a callback to
221 	 * this signal.
222 	 *
223 	 * Params:
224 	 *     oldPolicy = the old #SoupHSTSPolicy value
225 	 *     newPolicy = the new #SoupHSTSPolicy value
226 	 */
227 	gulong addOnChanged(void delegate(HSTSPolicy, HSTSPolicy, HSTSEnforcer) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
228 	{
229 		return Signals.connect(this, "changed", dlg, connectFlags ^ ConnectFlags.SWAPPED);
230 	}
231 
232 	/**
233 	 * Emitted when @hsts_enforcer has upgraded the protocol
234 	 * for @message to HTTPS as a result of matching its domain with
235 	 * a HSTS policy.
236 	 *
237 	 * Params:
238 	 *     message = the message for which HSTS is being enforced
239 	 */
240 	gulong addOnHstsEnforced(void delegate(Message, HSTSEnforcer) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
241 	{
242 		return Signals.connect(this, "hsts-enforced", dlg, connectFlags ^ ConnectFlags.SWAPPED);
243 	}
244 }