123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238 |
-
- using EVCB_OCPP.Domain;
- using EVCB_OCPP.WSServer;
- using NLog;
- using OCPPPackage.Profiles;
- using SuperWebSocket;
- using SuperWebSocket.SubProtocol;
- using System;
- using System.Collections.Generic;
- using System.Configuration;
- using System.Linq;
- using System.Net;
- using System.Net.Security;
- using System.Security.Cryptography.X509Certificates;
- using System.Text;
- namespace OCPPServer.Protocol
- {
- public class OCPPWSServer : WebSocketServer<ClientData>
- {
- static private ILogger logger = NLog.LogManager.GetCurrentClassLogger();
- /// <summary>
- /// 可允許連線Clinet數
- /// </summary>
- public int connectNum { get; set; }
- /// <summary>
- /// 是否限制連線Clinet數
- /// </summary>
- public bool beConnectLimit { get; set; }
- /// <summary>
- /// Initializes a new instance of the <see cref="WebSocketServer"/> class.
- /// </summary>
- /// <param name="subProtocols">The sub protocols.</param>
- public OCPPWSServer(IEnumerable<ISubProtocol<ClientData>> subProtocols)
- : base(subProtocols)
- {
- }
- /// <summary>
- /// Initializes a new instance of the <see cref="WebSocketServer"/> class.
- /// </summary>
- /// <param name="subProtocol">The sub protocol.</param>
- public OCPPWSServer(ISubProtocol<ClientData> subProtocol)
- : base(subProtocol)
- {
- }
- /// <summary>
- /// Initializes a new instance of the <see cref="WebSocketServer"/> class.
- /// </summary>
- public OCPPWSServer()
- : base(new List<ISubProtocol<ClientData>>())
- {
- }
- protected override bool ValidateClientCertificate(ClientData session, object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
- {
- // Console.WriteLine(string.Format("{0} :{1}", session.ChargeBoxId + " ValidateClientCertificate", sslPolicyErrors));
- return true;
- // return base.ValidateClientCertificate(session, sender, certificate, chain, sslPolicyErrors);
- }
- protected override bool ValidateHandshake(ClientData session, string origin)
- {
- session.ISOCPP20 = session.SecWebSocketProtocol.ToLower().Contains("ocpp2.0");
- int securityProfile = 0;
- string authorizationKey = string.Empty;
- if (string.IsNullOrEmpty(session.Path))
- {
- logger.Warn("===========================================");
- logger.Warn("session.Path EMPTY");
- logger.Warn("===========================================");
- }
- string[] words = session.Path.Split('/');
- session.ChargeBoxId = words.Last();
-
- foreach(var denyModel in GlobalConfig.DenyModelNames)
- {
- if (string.IsNullOrEmpty(denyModel)) break;
- if (session.ChargeBoxId.StartsWith(denyModel))
- {
- StringBuilder responseBuilder = new StringBuilder();
- responseBuilder.AppendFormatWithCrCf(@"HTTP/{0} {1} {2}", "1.1",
- (int)HttpStatusCode.Unauthorized, @"Unauthorized");
- responseBuilder.AppendWithCrCf();
- string sb = responseBuilder.ToString();
- byte[] data = Encoding.UTF8.GetBytes(sb);
- ((IWebSocketSession)session).SendRawData(data, 0, data.Length);
- logger.Info(sb);
- return false;
- }
- }
- if (ConfigurationManager.AppSettings["MaintainMode"] == "1")
- {
- session.ChargeBoxId = session.ChargeBoxId + "_2";
- }
- logger.Info(string.Format("ValidateHandshake: {0}", session.Path));
- bool isExistedSN = false;
- bool authorizated = false;
- using (var db = new MainDBContext())
- {
- var machine = db.Machine.Where(x => x.ChargeBoxId == session.ChargeBoxId && x.IsDelete == false).Select(x => new { x.CustomerId, x.Id }).FirstOrDefault();
- session.CustomerName = machine == null ? "Unknown" : db.Customer.Where(x => x.Id == machine.CustomerId).Select(x => x.Name).FirstOrDefault();
- session.CustomerId = machine == null ? Guid.Empty : machine.CustomerId;
- session.MachineId = machine == null ? String.Empty : machine.Id;
- isExistedSN = machine == null ? false : true;
- if (!isExistedSN)
- {
- StringBuilder responseBuilder = new StringBuilder();
- responseBuilder.AppendFormatWithCrCf(@"HTTP/{0} {1} {2}", "1.1",
- (int)HttpStatusCode.NotFound, @"Not Found");
-
- responseBuilder.AppendWithCrCf();
- string sb = responseBuilder.ToString();
- byte[] data = Encoding.UTF8.GetBytes(sb);
- ((IWebSocketSession)session).SendRawData(data, 0, data.Length);
- logger.Info(sb);
- return false;
- }
- var configVaule = db.MachineConfiguration.Where(x => x.ChargeBoxId == session.ChargeBoxId && x.ConfigureName == StandardConfiguration.SecurityProfile)
- .Select(x => x.ConfigureSetting).FirstOrDefault();
- int.TryParse(configVaule, out securityProfile);
- if (session.ISOCPP20)
- {
- // 1.6 server only support change server function
- securityProfile = 0;
- }
- }
- if (securityProfile == 3 && session.UriScheme == "ws")
- {
- StringBuilder responseBuilder = new StringBuilder();
- responseBuilder.AppendFormatWithCrCf(@"HTTP/{0} {1} {2}", "1.1",
- (int)HttpStatusCode.Unauthorized, @"Unauthorized");
- responseBuilder.AppendWithCrCf();
- string sb = responseBuilder.ToString();
- byte[] data = Encoding.UTF8.GetBytes(sb);
- ((IWebSocketSession)session).SendRawData(data, 0, data.Length);
- logger.Info(sb);
- return false;
- }
- if ((securityProfile == 1 || securityProfile == 2))
- {
- if (securityProfile == 2 && session.UriScheme == "ws")
- {
- authorizated = false;
- }
- if (session.Items.ContainsKey("Authorization") || session.Items.ContainsKey("authorization"))
- {
- using (var db = new MainDBContext())
- {
- authorizationKey = db.MachineConfiguration.Where(x => x.ChargeBoxId == session.ChargeBoxId && x.ConfigureName == StandardConfiguration.AuthorizationKey)
- .Select(x => x.ConfigureSetting).FirstOrDefault();
- if (session.ISOCPP20)
- {
- // 1.6 server only support change server function
- securityProfile = 0;
- }
- }
- logger.Info("***********Authorization ");
- if (!string.IsNullOrEmpty(authorizationKey))
- {
- string base64Encoded = session.Items.ContainsKey("Authorization") ? session.Items["Authorization"].ToString().Replace("Basic ", "") : session.Items["authorization"].ToString().Replace("Basic ", "");
- byte[] data = Convert.FromBase64String(base64Encoded);
- string[] base64Decoded = System.Text.ASCIIEncoding.ASCII.GetString(data).Split(':');
- logger.Info("***********Authorization " + System.Text.ASCIIEncoding.ASCII.GetString(data));
- if (base64Decoded.Count() == 2 && base64Decoded[0] == session.ChargeBoxId && base64Decoded[1] == authorizationKey)
- {
- authorizated = true;
- }
- }
- }
- else
- {
- authorizated = true;
- }
- if (!authorizated)
- {
- StringBuilder responseBuilder = new StringBuilder();
- responseBuilder.AppendFormatWithCrCf(@"HTTP/{0} {1} {2}", "1.1",
- (int)HttpStatusCode.Unauthorized, @"Unauthorized");
- responseBuilder.AppendWithCrCf();
- string sb = responseBuilder.ToString();
- byte[] data = Encoding.UTF8.GetBytes(sb);
- ((IWebSocketSession)session).SendRawData(data, 0, data.Length);
- logger.Info(sb);
- return false;
- }
- }
-
- return true;
- }
- }
- }
|