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 }