/// <summary>3a) Receive a DHEWithCertificate, verify the certificate and DHE and /// send a Confirm that you are ready to Verify the stack and start the /// system.</summary> /// <param name="sa">A security association that we wish to perform the /// specified control operation on.</param> /// <param name="scm">The received SecurityControlMessage.</param> /// <param name="scm_reply">A prepared reply message (with headers and such.</param> /// <param name="return_path">Where to send the result.</param> /// <param name="low_level_sender">We expect the return_path to not be an edge or /// some other type of "low level" sender, so this contains the parsed out value.</param> protected void HandleControlDHEWithCertificates(PeerSecAssociation sa, SecurityControlMessage scm, SecurityControlMessage scm_reply, ISender return_path, ISender low_level_sender) { ProtocolLog.WriteIf(ProtocolLog.Security, GetHashCode() + " Received DHEWithCertificate from: " + low_level_sender); if (sa == null) { throw new Exception("No valid SA!"); } byte[] cert = new byte[scm.Certificate.Length]; scm.Certificate.CopyTo(cert, 0); X509Certificate rcert = new X509Certificate(cert); HashAlgorithm sha1 = new SHA1CryptoServiceProvider(); scm.Verify((RSACryptoServiceProvider)rcert.RSA, sha1); _ch.Verify(rcert, low_level_sender); sa.RemoteCertificate = rcert; sa.RDHE.Value = scm.DHE; scm_reply.LocalCookie = scm.RemoteCookie; scm_reply.RemoteCookie = scm.LocalCookie; scm_reply.Hash = MemBlock.Reference(sha1.ComputeHash((byte[])scm.Packet)); scm_reply.Type = SecurityControlMessage.MessageType.Confirm; lock (_private_key_lock) { scm_reply.Sign(_private_key, sha1); } ICopyable to_send = new CopyList(Security, SecureControl, scm_reply.Packet); _rrman.SendRequest(return_path, ReqrepManager.ReqrepType.Request, to_send, this, sa); ProtocolLog.WriteIf(ProtocolLog.Security, GetHashCode() + " Successful DHEWithCertificate from: " + low_level_sender); }
/// <summary>3b) Receive a Confirm, verify the entire stack and send a Confirm /// 4a)Receive a Confirm, verify the entire stack and all set to go</summary> /// <param name="sa">A security association that we wish to perform the /// specified control operation on.</param> /// <param name="scm">The received SecurityControlMessage.</param> /// <param name="scm_reply">A prepared reply message (with headers and such.</param> /// <param name="return_path">Where to send the result.</param> /// <param name="low_level_sender">We expect the return_path to not be an edge or /// some other type of "low level" sender, so this contains the parsed out value.</param> protected void HandleControlConfirm(PeerSecAssociation sa, SecurityControlMessage scm, SecurityControlMessage scm_reply, ISender return_path, ISender low_level_sender) { ProtocolLog.WriteIf(ProtocolLog.Security, GetHashCode() + " Received Confirm from: " + low_level_sender); if (sa == null) { throw new Exception("No valid SA!"); } HashAlgorithm sha1 = new SHA1CryptoServiceProvider(); scm.Verify((RSACryptoServiceProvider)sa.RemoteCertificate.RSA, sha1); if (return_path == low_level_sender) { sa.VerifyResponse(scm.Hash); } else { sa.VerifyRequest(scm.Hash); scm_reply.LocalCookie = scm.RemoteCookie; scm_reply.RemoteCookie = scm.LocalCookie; scm_reply.Hash = sa.DHEWithCertificateAndCAsInHash.Value; scm_reply.Type = SecurityControlMessage.MessageType.Confirm; lock (_private_key_lock) { scm_reply.Sign(_private_key, sha1); } ICopyable to_send = new CopyList(SecureControl, scm_reply.Packet); return_path.Send(to_send); } sa.Enable(); ProtocolLog.WriteIf(ProtocolLog.Security, GetHashCode() + " Successful Confirm from: " + low_level_sender); }
// /////////////// // Methods // /////////////// /*** Immediately close the underlying edge, and don't warn the other node. * Prefer Connection.Close if possible. This is idempotent. * @return the old state, new state pair. */ public Pair <ConnectionState, ConnectionState> Abort() { var res = _state.Update(delegate(ConnectionState old_state) { if (old_state.Disconnected) { return(old_state); } else { return(new ConnectionState(old_state.Edge, old_state.StatusMessage, old_state.PeerLinkMessage, true)); } }); if (res.First != res.Second) { ProtocolLog.WriteIf(ProtocolLog.Connections, String.Format( "Abort called on {0}", this)); //Only send the event if there is an actual change var ev = StateChangeEvent; if (null != ev) { ev(this, res); } } return(res); }
/* * Stop the underlying EdgeListener. This is important to stop any * thread and resources that might be allocated by that EdgeListener. */ public void Stop() { foreach (Edge e in _unannounced.Values) { try { e.Close(); } catch (Exception ex) { ProtocolLog.WriteIf(ProtocolLog.Exceptions, ex.ToString()); } } _running = false; if (_rrm_fe != null) { _rrm_fe.TryCancel(); } if (_edge_fe != null) { _edge_fe.TryCancel(); } if (_timer_thread != null) { _timer_thread.Join(); } _el.Stop(); }
/// <summary>1b) Receive a Cookie which responds with a CookieResponse</summary> /// <param name="sa">A security association that we wish to perform the /// specified control operation on.</param> /// <param name="calc_cookie">Cookie value for the association sender.</param> /// <param name="scm">The received SecurityControlMessage.</param> /// <param name="scm_reply">A prepared reply message (with headers and such.</param> /// <param name="return_path">Where to send the result.</param> /// <param name="low_level_sender">We expect the return_path to not be an edge or /// some other type of "low level" sender, so this contains the parsed out value.</param> protected void HandleControlCookie(PeerSecAssociation sa, MemBlock calc_cookie, SecurityControlMessage scm, SecurityControlMessage scm_reply, ISender return_path, ISender low_level_sender) { ProtocolLog.WriteIf(ProtocolLog.Security, String.Format( "{0}, Received Cookie from: {1}, In-Cookie: {2}", GetHashCode(), low_level_sender, scm.LocalCookie)); scm_reply.Type = SecurityControlMessage.MessageType.CookieResponse; scm_reply.RemoteCookie = scm.LocalCookie; scm_reply.LocalCookie = calc_cookie; if (SecurityPolicy.GetPolicy(scm.SPI).PreExchangedKeys) { scm_reply.CAs = new List <MemBlock>(0); } else { scm_reply.CAs = _ch.SupportedCAs; } ICopyable to_send = new CopyList(SecureControl, scm_reply.Packet); return_path.Send(to_send); ProtocolLog.WriteIf(ProtocolLog.Security, String.Format( "{0}, Successful Cookie from: {1}, Out-Cookie: {2}", GetHashCode(), low_level_sender, calc_cookie)); }
public static string Request(string url, Dictionary <string, string> parameters) { ProtocolLog.WriteIf(SocialLog.SVPNLog, String.Format("HTTP REQUEST: {0} {1} {2}", DateTime.Now.TimeOfDay, url, parameters["m"])); return(Request(url, Encoding.ASCII.GetBytes(UrlEncode(parameters)))); }
override protected bool HandleIncoming(MemBlock data, out MemBlock app_data) { app_data = null; int count = 0; lock (_buffer_sync) { if (data != null) { data.CopyTo(_buffer, 0); _read.Write(_buffer, data.Length); } count = _ssl.Read(_buffer, _buffer.Length); if (count > 0) { app_data = MemBlock.Copy(_buffer, 0, count); } } if (app_data != null) { // If the read was successful, Dtls has received an incoming data // message and decrypted it return(true); } else { SslError error = _ssl.GetError(count); if (error == SslError.SSL_ERROR_WANT_READ) { if (SslState == SslState.OK) { UpdateState(States.Active); // In the SslCtx verify, there's no way to get the underlying Sender _ch.Verify(RemoteCertificate, Sender); } HandleWouldBlock(); } else if (error == SslError.SSL_ERROR_SSL) { var ose = new OpenSslException(); Close("Received unrecoverable error: " + ose.ToString()); throw ose; } else if (error == SslError.SSL_ERROR_ZERO_RETURN) { Close("Received clean close notification"); } else { ProtocolLog.WriteIf(ProtocolLog.SecurityExceptions, "Receive other: " + error); } } return(false); }
/// <summary>Timercall back for internal ssl timeout.</summary> private void HandleWouldBlock(DateTime now) { Interlocked.Exchange(ref _fe_lock, 0); try { HandleWouldBlock(); } catch (Exception e) { Close("Unhandled exception: " + e.ToString()); ProtocolLog.WriteIf(ProtocolLog.SecurityExceptions, this + "\n" + e.ToString()); } }
/// <summary>1a) Send a Cookie</summary> /// <param name="sa">A security association that we wish to perform the /// specified control operation on.</param> protected void HandleControlNoSuchSA(PeerSecAssociation sa) { if (sa == null) { ProtocolLog.WriteIf(ProtocolLog.Security, GetHashCode() + " NoSuchSA received, but we have no SA either!"); } else { ProtocolLog.WriteIf(ProtocolLog.Security, GetHashCode() + " NoSuchSA received, handling..."); StartSA(sa); } }
///<summary>This closes the SA and cleans up its state.</summary> ///<returns>Returns true, if the first to call close.</summary> virtual public bool Close(string reason) { string string_rep = ToString(); if (Interlocked.Exchange(ref _closed, 1) == 1) { return(false); } UpdateState(States.Closed); ProtocolLog.WriteIf(ProtocolLog.Security, string_rep + " closing because " + reason); return(true); }
/// <summary>If the request really failed, we'll have to close the SA.</summary> public void HandleError(ReqrepManager man, int message_number, ReqrepManager.ReqrepError err, ISender returnpath, object state) { if (man.RequestActive(message_number)) { return; } PeerSecAssociation sa = state as PeerSecAssociation; ProtocolLog.WriteIf(ProtocolLog.Security, "Forcing reset due to timeout: " + sa); sa.Reset(); }