/// <summary> /// Validates the password for a username token. /// </summary> private void VerifyPassword(string userName, string password) { SecureChannelContext context = SecureChannelContext.Current; if (context != null && m_credentialValidator.IsValid(userName, password)) { // Log accepted credetials m_Logger.LogAuthInfo(userName, password, true, context); } else { // Log rejected credentials m_Logger.LogAuthInfo(userName, password, false, context); // construct translation object with default text. TranslationInfo info = new TranslationInfo( "InvalidPassword", "en-US", "Specified password is not valid for user '{0}'.", userName); // create an exception with a vendor defined sub-code. throw new ServiceResultException(new ServiceResult( StatusCodes.BadIdentityTokenRejected, "InvalidPassword", "http://opcfoundation.org/UA/Sample/", new LocalizedText(info))); } }
/// <summary> /// Create and Activate a session without security. /// </summary> /// <remarks> /// The request header is used to call services directly, /// without establishing a session with a client. /// </remarks> /// <param name="server">The server to connect to.</param> /// <param name="sessionName">A session name.</param> /// <returns>The request header for the session.</returns> public static RequestHeader CreateAndActivateSession( this SessionServerBase server, string sessionName, double sessionTimeout = DefaultSessionTimeout, uint maxResponseMessageSize = DefaultMaxResponseMessageSize) { // Find TCP endpoint var endpoints = server.GetEndpoints(); var endpoint = endpoints.FirstOrDefault(e => e.TransportProfileUri.Equals(Profiles.UaTcpTransport) || e.TransportProfileUri.Equals(Profiles.HttpsBinaryTransport)); if (endpoint == null) { throw new System.Exception("Unsupported transport profile."); } // no security endpoint.SecurityMode = MessageSecurityMode.None; endpoint.SecurityPolicyUri = SecurityPolicies.None; var context = new SecureChannelContext( sessionName, endpoint, RequestEncoding.Binary); // set security context SecureChannelContext.Current = context; var requestHeader = new RequestHeader(); // Create session var response = server.CreateSession( requestHeader, null, null, null, sessionName, null, null, sessionTimeout, maxResponseMessageSize, out var sessionId, out var authenticationToken, out sessionTimeout, out var serverNonce, out var serverCertificate, out var endpointDescriptions, out var serverSoftwareCertificates, out var signatureData, out var maxRequestMessageSize); ValidateResponse(response); // Activate session requestHeader.AuthenticationToken = authenticationToken; response = server.ActivateSession(requestHeader, signatureData, null, new StringCollection(), null, null, out serverNonce, out var results, out var diagnosticInfos); ValidateResponse(response); return(requestHeader); }
/// <summary> /// Record a log entry that has a secure channel context. The secure channel context includes /// the IP address of the client. /// </summary> /// <param name="entry">The log entry to record.</param> /// <param name="context">The secure channel context.</param> public void Log(LogEntry entry, SecureChannelContext context) { if (entry != null) { ObjectEntry withTimestamp = new ObjectEntry(); withTimestamp.Add("Id", Entry.For(Interlocked.Increment(ref m_Id))); withTimestamp.Add("TimeLogged", Entry.For(DateTime.UtcNow)); withTimestamp.Add(entry.getRequestName(), entry); if (context != null) { withTimestamp.Add("Context", Entry.For(context)); } write(withTimestamp.JsonText()); } }
public static Entry For(SecureChannelContext secureChannelContext) { if (secureChannelContext == null) { return(new NullEntry()); } else { ObjectEntry entry = new ObjectEntry(); entry.Add("SecureChannelId", For(secureChannelContext.SecureChannelId)); entry.Add("MessageEncoding", For(secureChannelContext.MessageEncoding)); entry.Add("EndpointURL", For(secureChannelContext.EndpointDescription)); entry.Add("RemoteIP", For(secureChannelContext.RemoteIP)); entry.Add("RemotePort", For(secureChannelContext.RemotePort)); return(entry); } }
/// <summary> /// Validates the request. /// </summary> public virtual void ValidateRequest(RequestHeader requestHeader, RequestType requestType) { if (requestHeader == null) { throw new ArgumentNullException("requestHeader"); } lock (m_lock) { // get the request context for the current thread. SecureChannelContext context = SecureChannelContext.Current; if (context == null || !IsSecureChannelValid(context.SecureChannelId)) { UpdateDiagnosticCounters(requestType, true, true); throw new ServiceResultException(StatusCodes.BadSecureChannelIdInvalid); } // verify that session has been activated. if (!m_activated) { if (requestType != RequestType.CloseSession) { UpdateDiagnosticCounters(requestType, true, true); throw new ServiceResultException(StatusCodes.BadSessionNotActivated); } } // verify timestamp. if (requestHeader.Timestamp.AddMilliseconds(m_maxRequestAge) < DateTime.UtcNow) { UpdateDiagnosticCounters(requestType, true, false); throw new ServiceResultException(StatusCodes.BadInvalidTimestamp); } // request accepted. UpdateDiagnosticCounters(requestType, false, false); } }
/// <summary> /// Record authentication information provided to the honeypot. This is not a separate OPC UA request, /// so it is not logged by LogIncomingRequest(). /// </summary> /// <param name="username">The username supplied.</param> /// <param name="password">The password supplied.</param> /// <param name="accepted">Whether the username and password were accepted.</param> /// <param name="context">The secure channel context.</param> public void LogAuthInfo(string username, string password, bool accepted, SecureChannelContext context) { LogEntry entry = LogEntry.For(username, password, accepted); Log(entry, context); }