Category: IT Stuff


SSRS 2016 Error when using HTTPS

My first surprise, I couldn’t simply enable HTTPS on the Web Portal (in Reporting Services Configuration Manager). Straight away this causes an error when trying to access https://host.domain/reports

The service is not available.

The report server isn’t configured properly. Contact your system administrator to resolve the issue. System administrators: The report server Web Portal URLs and Web Service URLs don’t match. Use Reporting Services Configuration Manager to configure the URLs and ensure they match.

Seemingly behind the scenes the web portal is communicating with the web service (and it doesn’t know to use a different URL), so this also needs configuring for HTTPS. After setting this up, I can hit the basic web portal pages but if I try and view my subscriptions for example I receive an error;

Not overly helpful, and doing some snooping in Chrome Developer Tools simply shows the HTTP request returning a 500 error.

There is nothing in the event log on the SSRS server, but there are a few lengthy error messages in the reporting services log files;

Microsoft.ReportingServices.Portal.WebHost!reportserverwebapp!6!09/04/2018-07:59:37:: e ERROR: [m9yd0rtt]: OData exception occurred: System.Net.WebException: The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel. ---> System.Security.Authentication.AuthenticationException: The remote certificate is invalid according to the validation procedure.
at System.Net.Security.SslState.StartSendAuthResetSignal(ProtocolToken message, AsyncProtocolRequest asyncRequest, Exception exception)
at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Net.TlsStream.ProcessAuthentication(LazyAsyncResult result)
at System.Net.TlsStream.Write(Byte[] buffer, Int32 offset, Int32 size)
at System.Net.ConnectStream.WriteHeaders(Boolean async)
--- End of inner exception stack trace ---
at System.Web.Services.Protocols.WebClientProtocol.GetWebResponse(WebRequest request)
at System.Web.Services.Protocols.HttpWebClientProtocol.GetWebResponse(WebRequest request)
at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters)
at Microsoft.SqlServer.ReportingServices2010.ReportingService2010.ListExtensions(String ExtensionType)
at Microsoft.SqlServer.ReportingServices2010.RSConnection2010.<>c__DisplayClass75.<ListExtensions>b__74()
at Microsoft.SqlServer.ReportingServices2010.RSConnection2010.SoapMethodWrapper`1.ExecuteMethod(Boolean setConnectionProtocol)
at Microsoft.SqlServer.ReportingServices2010.RSConnection2010.SoapMethodWrapper`1.ExecuteMethod()
at Microsoft.SqlServer.ReportingServices2010.RSConnection2010.ListExtensions(String extensionType)
at Microsoft.ReportingServices.Portal.Services.SoapProxy.SoapRS2010Proxy.<>c__DisplayClass41.<ListExtensions>b__40()
at Microsoft.ReportingServices.Portal.Services.SoapProxy.SoapAuthenticationHelper.ExecuteWithWindowsAuth[TReturn](SoapHttpClientProtocol soapClient, IPrincipal userPrincipal, Func`1 func)
at Microsoft.ReportingServices.Portal.Services.SoapProxy.SoapAuthenticationHelper.ExecuteWithCorrespondingAuthMechanism[TReturn](SoapHttpClientProtocol soapClient, IPrincipal userPrincipal, Func`1 func)
at Microsoft.ReportingServices.Portal.Services.SoapProxy.SoapRS2010Proxy.ListExtensions(IPrincipal userPrincipal, String extensionType)
at Microsoft.ReportingServices.Portal.Repositories.SystemService.ListExtensions(IPrincipal userPrincipal, ExtensionType extensionType)
at Microsoft.ReportingServices.Portal.Repositories.SystemService.PopulateLocalizedExtensionNames(IPrincipal userPrincipal, List`1 subscriptions)
at Microsoft.ReportingServices.Portal.ODataWebApi.V1.Controllers.SubscriptionsController.GetEntitySet(String castName)
at Microsoft.ReportingServices.Portal.ODataWebApi.V1.Controllers.Reflection.EntitySetReflectionODataController`1.GetRoot(ODataPath oDataPath, Int32& index)
at Microsoft.ReportingServices.Portal.ODataWebApi.V1.Controllers.Reflection.ReflectionODataController`1.Get(ODataPath oDataPath)
at lambda_method(Closure , Object , Object[] )
at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass10.<GetExecutor>b__9(Object instance, Object[] methodParameters)
at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext, IDictionary`2 arguments, CancellationToken cancellationToken)
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Filters.ActionFilterAttribute.<ExecuteActionFilterAsyncCore>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Controllers.ExceptionFilterResult.<ExecuteAsync>d__0.MoveNext().

Microsoft.ReportingServices.Portal.WebHost!reportserverwebapp!18!09/04/2018-08:00:58:: e ERROR: [dq2umtxh]: OData exception occurred: System.Net.WebException: The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel. ---> System.Security.Authentication.AuthenticationException: The remote certificate is invalid according to the validation procedure.
at System.Net.Security.SslState.StartSendAuthResetSignal(ProtocolToken message, AsyncProtocolRequest asyncRequest, Exception exception)
at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Net.TlsStream.ProcessAuthentication(LazyAsyncResult result)
at System.Net.TlsStream.Write(Byte[] buffer, Int32 offset, Int32 size)
at System.Net.ConnectStream.WriteHeaders(Boolean async)
--- End of inner exception stack trace ---
at System.Web.Services.Protocols.WebClientProtocol.GetWebResponse(WebRequest request)
at System.Web.Services.Protocols.HttpWebClientProtocol.GetWebResponse(WebRequest request)
at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters)
at Microsoft.SqlServer.ReportingServices2010.ReportingService2010.ListExtensions(String ExtensionType)
at Microsoft.SqlServer.ReportingServices2010.RSConnection2010.<>c__DisplayClass75.<ListExtensions>b__74()
at Microsoft.SqlServer.ReportingServices2010.RSConnection2010.SoapMethodWrapper`1.ExecuteMethod(Boolean setConnectionProtocol)
at Microsoft.SqlServer.ReportingServices2010.RSConnection2010.SoapMethodWrapper`1.ExecuteMethod()
at Microsoft.SqlServer.ReportingServices2010.RSConnection2010.ListExtensions(String extensionType)
at Microsoft.ReportingServices.Portal.Services.SoapProxy.SoapRS2010Proxy.<>c__DisplayClass41.<ListExtensions>b__40()
at Microsoft.ReportingServices.Portal.Services.SoapProxy.SoapAuthenticationHelper.ExecuteWithWindowsAuth[TReturn](SoapHttpClientProtocol soapClient, IPrincipal userPrincipal, Func`1 func)
at Microsoft.ReportingServices.Portal.Services.SoapProxy.SoapAuthenticationHelper.ExecuteWithCorrespondingAuthMechanism[TReturn](SoapHttpClientProtocol soapClient, IPrincipal userPrincipal, Func`1 func)
at Microsoft.ReportingServices.Portal.Services.SoapProxy.SoapRS2010Proxy.ListExtensions(IPrincipal userPrincipal, String extensionType)
at Microsoft.ReportingServices.Portal.Repositories.SystemService.ListExtensions(IPrincipal userPrincipal, ExtensionType extensionType)
at Microsoft.ReportingServices.Portal.Repositories.SystemService.PopulateLocalizedExtensionNames(IPrincipal userPrincipal, List`1 subscriptions)
at Microsoft.ReportingServices.Portal.ODataWebApi.V1.Controllers.SubscriptionsController.GetEntitySet(String castName)
at Microsoft.ReportingServices.Portal.ODataWebApi.V1.Controllers.Reflection.EntitySetReflectionODataController`1.GetRoot(ODataPath oDataPath, Int32& index)
at Microsoft.ReportingServices.Portal.ODataWebApi.V1.Controllers.Reflection.ReflectionODataController`1.Get(ODataPath oDataPath)
at lambda_method(Closure , Object , Object[] )
at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass10.<GetExecutor>b__9(Object instance, Object[] methodParameters)
at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext, IDictionary`2 arguments, CancellationToken cancellationToken)
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Filters.ActionFilterAttribute.<ExecuteActionFilterAsyncCore>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Controllers.ExceptionFilterResult.<ExecuteAsync>d__0.MoveNext().

Something is moaning about trust/SSL. I am using a valid wildcard certificate and don’t see any certificate related errors in the browser.

Digging around, google seems to suggest changing the “SecureConnectionLevel” parameter in rsreportserver.config to a 0, but it was already set to 0 on my server. This didn’t help.

In the end, I was able to resolve the issue by setting “SecureConnectionLevel” to 3 and adding the fully qualified server/domain name (FQDN) in the “UrlRoot” parameter (i.e. to https://host.domain) then restarting the service (either in Reporting Services Configuration Manager or Windows Service Manager).

Hope it works for you!

We use an off the shelf product at work which can send e-mails. The e-mails come from the currently logged in user and the way this is achieved is by using Exchange Web Services. The code probably looks something along the lines of;

ExchangeService service = new ExchangeService();
service.Credentials = new WebCredentials("impersonationusername@domain.com", "password", "");
service.UseDefaultCredentials = false;
service.AutodiscoverUrl(from, new AutodiscoverRedirectionUrlValidationCallback(RedirectionUrlValidationCallback));
service.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.PrincipalName, "sender");
EmailMessage email = new EmailMessage(service);
email.ToRecipients.Add("recipient");
email.Subject = "subject";
email.Send();

Our e-mail provider is Office365 and recently some users have been unable to send e-mails from this product. We followed the usual troubleshooting process and were pretty convinced we had ruled out everything at our end. On top of this we used the Microsoft Remote Connectivity Analyzer (https://testconnectivity.microsoft.com) which was giving the same result;

ExchangeImpersonation SOAP header must not exist for this type of OAuth token

We haven’t made any changes to the mailboxes recently and they were previously working so it must be an issue Microsoft’s end. We logged a ticket and a week of back and forth later we have a solution (via powershell);

1. Set-ExecutionPolicy RemoteSigned
2. $UserCredential = Get-Credential
3. $Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $UserCredential -Authentication Basic -AllowRedirection
4. Import-PSSession $Session
5. New-MoveRequest -Identity "impersonationusername@domain.com"

You can check the status of the execution of this command by:
Get-MoveRequest -Identity "impersonationusername@domain.com"

Microsoft were unable to provide a real reason for this other- but said something along the lines of; “something has become corrupt and moving the impersonation mailbox to a different database causes some form of rebuild”.

I hope this works for you too!

Further to https://tickett.wordpress.com/2018/08/08/unlock-remove-hp-probook-430-g3-bios-password/ I have now managed to unlock the remaining BIOSs.

I ended up ordering a SOIC8 clip and flashing the Winbond flash chip directly using a Raspberry Pi and flashrom. I used this blog post as to get me started but struggled with a few bits- so hopefully I can fill in the gaps below.

I found the pin mapping for the probook’s BIOS (winbond flash chip) here and the Pi’s GPIO pins are widely documented. Here is the mapping I used between the two;

BIOS (25q128fvsq) Name Function Raspberry Pi
1 /CS Chip Select 24
2 DO Data Output 21
3 /WP Write Protect 1 or 17 (3.3V)
4 GND Ground 25
5 DI Data Input 19
6 CLK Serial Clock Input 23
7 /HOLD or /RESET Hold or Reset 1 or 17 (3.3V)
8 VCC Power Supply 1 or 17 (3.3V)

Which looked something a bit like;

IMG_20180826_213032_8

Attaching the SOIC8 clip to the BIOS chip was a royal PITA! I had a bit of a nightmare getting the Pi to detect the chip (using the command;

flashrom -p linux_spi:dev=/dev/spidev0.0

I was repeatedly getting the message;

No EEPROM/flash device found.

After disconnecting/reconnecting/wiggling/trying/trying and trying again the Pi finally detected and read the currently locked BIOS from the W25Q128 chip. But it appeared to be a one-off and I never managed to get it to read/write again. I was even convinced I had damaged the SOIC8 clip and ordered a replacement. Turns out I just had to set the spi speed. I had almost a 100% success rate when issuing the following command;

flashrom -p linux_spi:dev=/dev/spidev0.0,spispeed=1000

Reading the current chip contents using;

flashrom -r locked_bios.bin -VVV -p linux_spi:dev=/dev/spidev0.0,spispeed=1000

Oddly, some of the laptops detected the W25Q128 chip but some identified it as being either GD25Q128B or GD25Q128C and required including the chip in the read/write command. I went with GD25Q128B but suspect either would have worked;

flashrom -r locked_bios.bin -VVV -p linux_spi:dev=/dev/spidev0.0,spispeed=1000 -c GD25Q128B

 

I was out of my depth trying to figure out what to modify in the BIOS dump to remove the password, but fortunately the folks over on the ghostlyhacks forum took care of that for me. I was then able to compare the locked/unlocked and identify the region which they had patched (and re-apply the same technique to a number of additional dumps).

Here is the unlocked section you will need to patch (you can also download from https://tickett.net/downloads/probook_clear_bios_password.bin)

43 00 72 00 65 00 64 00 00 00 00 00 00 00 00 00 00 00 FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF FF FF 00 00 00 00 FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 FF FF FF FF 00 00 00 00 FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 FF FF FF FF 00 00 00 00 FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 FF FF FF FF 00 00 00 00 FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 FF FF FF FF 00 00 00 00 FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 FF FF FF FF 00 00 00 00 FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 FF FF FF FF 00 00 00 00 FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 FF FF FF FF 00 00 00 00 FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 FF FF FF FF 00 00 00 00 FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 FF FF FF FF 00 00 00 00 FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 FF FF FF FF 00 00 00 00 FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 FF FF FF FF 00 00 00 00 FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 FF FF FF FF 00 00 00 00 FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 FF FF FF FF 00 00 00 00 FF FF FF FF 00 00 00 00 FF FF AA 55 3F 00 07 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 3C 00 00 00 42 00 00 00 FF 87 66 F6 F3 8C 19 4A B4 AC F5 F0 B7 8E 4D 18 48 00 70 00 50 00 61 00 73 00 73 00 70 00 68 00 72 00 61 00 73 00 65 00 53 00 74 00 72 00 75 00 63 00 74 00 75 00 72 00 65 00 56 00 61 00 72 00 69 00 61 00 62 00 6C 00 65 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF AA 55 3F

Search the locked BIOS for the hex value; 43 00 72 00 65 00 64 and highlight the region ending 00 00 FF FF AA 55 3F (this appears several times, so make sure you get the right one, the selected region length should be E9B);

start

Now paste the unlocked bytes from above over the top (if you get a message saying “This operation changes the file-size. Do you want to proceed?” then you did something wrong.

Once you have patched the .bin file, you can write it back to the flash with the Pi using the command;

flashrom -w unlocked_bios.bin -VVV -p linux_spi:dev=/dev/spidev0.0,spispeed=1000

After powering the laptop up I was able to access the BIOS without the need for a password- bingo! Now I could reset to factory defaults, update to the latest BIOS (1.33 as of today) and go on my merry way!

Good luck!

We recently migrated our internal reports from SSRS 2008 R2 to SSRS 2016 and had issues with a custom assembly / dll.

The deployment process seemed roughly the same (this time copying the .dll to C:\Program Files\Microsoft SQL Server\MSRS13.MSSQLSERVER\Reporting Services\ReportServer\bin and modifying rssrvpolicy.config in c:\Program Files\Microsoft SQL Server\MSRS13.MSSQLSERVER\Reporting Services\ReportServer to give FullTrust), but while this allowed us to deploy the report and didn’t complain about the file being missing; we were getting #Error returned by the report.

After a lot of messing around, it turns out the .dll was set to target .net framework 3.5 (this was a requirement for SSRS 2008 R2). Now however, it seems the assembly needs to target .net framework 4 (for SSRS 2016). Once I changed this in Visual Studio, recompiled and deployed the new .dll, voila!

Having bought a few of these cracking little laptops off eBay recently, fully functional but with slightly annoying BIOS passwords, I thought i’d take a look at unlocking them.

HP support are somewhat helpful, in that you can simply open a support case and they will generate an SMC.BIN file. You will need to provide them the laptop serial and UUID (both can be found by pressing escape when powering on the laptop and then pressing F1 for system information at the boot menu.

The SMC.bin file will in theory, when placed in the root of a FAT32 formatted USB drive, inserted into the laptop and powered on whilst holding winkey + up arrow + down arrow gain access to the BIOS without the password. This worked on some of the laptops but the next step is to reset security settings to factory defaults which immediately prompts for the BIOS password- doh!

Anyway, after lots of scratching, I had the idea to try flashing the latest BIOS. Initially this seemed like a no go; when trying from windows you are prompted for the BIOS password, when trying from the boot menu you are prompted for the BIOS password. Eventually, I found there is a BIOS update option within the BIOS. So, here we go again… this time armed with a FAT32 USB stick with my SMC.BIN and N78_0127.bin (latest firmware v01.27);

  • boot the laptop holding winkey, up and down
  • SMC message confirms successful execution
  • access BIOS with F10 (no prompt for password)
  • select update BIOS
  • reboot and confirm BIOS showing correct revision
  • power down
  • boot the laptop again, holding winkey + up + down arrows
  • SMC message confirms successful execution
  • access BIOS with F10 (no prompt for password)
  • select reset security to factory defaults (bingo! no password prompt)
  • laptop reboots once and asks to press F1 to confirm reset
  • laptop reboots a second time and asks to press F1 to confirm reset
  • laptop reboots a third time and now has the latest BIOS with no password

The above process worked on a few of the laptops, but then I hit a snag where the SMC.BIN initially worked, the BIOS update was successful but I could no longer execute the SMC.BIN to access the BIOS and reset the security settings (it seemed like it wasn’t seeing the USB device or file). I suspect this may be because of a BIOS setting like; USB disabled, UEFI or secure boot perhaps, i’m still not entirely sure.

I was able to get back into the BIOS by placing the SMC.BIN file into the root of a SATA disk (using another computer to load the file on). A few more down!

I’m now stuck with a few more stubborn laptops which I’ve yet to get to detect/execute the SMC.bin. I suspect it may be a specific version of the firmware which has a bug (again perhaps coinciding with another setup like UEFI/secure boot or disabled USB)- the problematic machines seem to be running N78 v01.12.

I have been trying to build bootable recover/upgrade USB keys and using winkey + b whilst powering on, but I get a variety of beeps, flashing caps lock etc but no sign of the BIOS being upgraded. I suspect winkey + b doesn’t allow you to circumvent a BIOS password.

I still have a few tricks to try- fingers crossed. Watch this space!

It’s important to note HP didn’t supply any of the above instructions and had told me if the SMC.BIN didn’t work out of the box I would need a replacement motherboard for roughly £350.

So, 8 months since the original post; https://tickett.wordpress.com/2017/09/28/tools-to-run-an-it-company/ let’s see what’s changed…

Laptop Upgrades

Our newest laptops are all HP Probook 640 G1; The fourth generation and last to supersede the Elitebook 8440P whilst still fitting the HP docking stations we are using. Sooner or later we will have to bite the bullet and get some newer generation and replace some docking stations.

Printer Upgrade

The Xerox Phaser 6121MFP finally reached the end of days and got upgraded to a Xerox WorkCentre 6515N. Offering much the same features but much newer with more RAM, a faster processor and a few nice bonuses; Active Directory (LDAP) integration and duplex scanning/printing.

Version Control

Our development team have now moved from SVN to GIT. We are using GitLab Community Edition (hosted on-premise). I hope to share some of our practices and customisations soon. We feel GIT provides a more natural integration with Visual Studio and handles our collaboration better.

Support / Helpdesk / Ticket System

Over the Christmas period we wrote our own in-house helpdesk system which better fits our business. This continues to evolve each month and we hope to market it sometime in the future.

There should be a reasonable cost saving moving away from Solarwindows WebHelpDesk but we will be investing a large amount in developing the product and the biggest gains will be realised by the productivity improvements and enforced process/workflows.

Project Management

Once our in-house helpdesk system was live we quickly started work adding project managements features and moved away from Trello and Freedcamp. This will now prevent a lot of duplication previously keeping the disparate systems in sync.

Password Storage

We have now built a simple web based password manager with full and access control which we hope to market in the near future.

Internet Service Provider

After about 18 months of trying, Virgin Media Business has now been installed. The service is significantly poorer than I expected. Whilst we do often manage to achieve 100mb/s+ down and consistently 15mb/s up, the latency is poor (around 30ms) and the way they deliver static IP addresses is ridiculous (and forces you to use their router for the weird gre tunnel, you will need a minimum of 5 static IP addresses, the single IP will be assigned to the router itself and cannot be assigned to your own hardware).

We are now in a position where we want to monitor remote nodes (outside of our domain/LAN). Initially we were able to setup port forwarding on the remote network to allow traffic IN from our server to the agent on port 4700 (remembering to configure the windows firewall too). Then we hit a limitation with NetXMS server not allowing multiple nodes configured with the same ip/hostname (hopefully this will be resolved in a future release).

So we tried to flip the configuration so the remote agent connects in to our server. This proved a little challenging so i’ve documented how we got it working and some of the troubleshooting tips.

Enabling Logging

On the server server modify netxmsd.conf (on our server this was located at C:\NetXmsServer\etc). On the agent modify nxagentd.conf (on our agent this was found in C:\NetXMS\etc). Add;

LogFile = C:\path\to\log\log.txt
DebugLevel = 9

Then restart the NetXMS Core service (on the server) or NetXMS Agent service (on the agent).

**Make sure you change it back to 1 or remove it completely when you are done as the log file will grow very large, very quickly**

Creating the CA / Server Certificate

We wanted to do this with the bare minimum (most of the guides online were pages long). I was surprised there wasn’t an online tool to generate the certificate (perhaps I will build one sometime).

openssl genrsa -out ca.key 2048
openssl req -x509 -new -nodes -key ca.key -sha256 -days 10240 -out ca.pem

When prompted for Country, State, Organization etc we just hit enter to accept the default value. We then need to combine the key and certificate (we just used Notepad++)

-----BEGIN CERTIFICATE-----
MIIDYDCCAkigAwIBAgIJAPmfsLYXzwABMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
aWRnaXRzIFB0eSBMdGQwHhcNMTgwNjA2MTI1OTUyWhcNNDYwNjE5MTI1OTUyWjBF
MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEAnRDoS4m4YV4ePquEUkmSHMIr40mgtJIFzTj4bIZ8UySaZpfw1LLaXUVP
eck0xZM5q4GnOS8fVQfzZv5uwKs76cy3VLl/kJlBnyFSRdZsLnbqTJI7LT5qOkK7
C5ryDNymA+6UcvBGmq/+hyht4zFwM3GB0EA/BfpmpiEtyzOu327VjCWh5LWGa1E5
grUUAdFqLvKfUb0vIY6BDiFoGso8YjkY3n1V0BLIOqH/AyZeCODZxC5E9zH5teka
QLsEEVzQ87fgmyQz89vxxCyejODxU5HcLdo62BN38LytZhiQPI366KOAvrS/k44y
SDNa7oinvv2cE3X6T3s49P05QfcT4QIDAQABo1MwUTAdBgNVHQ4EFgQU77bOpRE5
RcbeYhJbHIqGPXaBsbswHwYDVR0jBBgwFoAU77bOpRE5RcbeYhJbHIqGPXaBsbsw
DwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAY+Vt/zwrMS8l5B+D
zuZ3awRKe2olD8zmLlxcKNbj5csf9ivCCjHc8WWmuF0wqkMwTst7caNSdVjQozV0
UNUBVe1X3fQ8o2qRutwnT4FqYSEuD+nzXEdj+n7opJKqiNBMkvJzimIUlEoQwdJB
X6LDrJaF5WCtcbX57CvkFrLo8p9efM1pWi62q4oynp+Uyr4mEWMzMT82mnz2mbV/
Djio7aZ5nh6g0453tEhaQXmAWvDdbfReIy/TnPG7RiHoUWuBigE2pEB8HXdrYP7o
+lHIuQUhH2Ah4obIJxy48DokMriNL8rv7rj1pEpVzg4au+Nk6K0CFx5T/c1xuHud
CrBTrw==
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAnRDoS4m4YV4ePquEUkmSHMIr40mgtJIFzTj4bIZ8UySaZpfw
1LLaXUVPeck0xZM5q4GnOS8fVQfzZv5uwKs76cy3VLl/kJlBnyFSRdZsLnbqTJI7
LT5qOkK7C5ryDNymA+6UcvBGmq/+hyht4zFwM3GB0EA/BfpmpiEtyzOu327VjCWh
5LWGa1E5grUUAdFqLvKfUb0vIY6BDiFoGso8YjkY3n1V0BLIOqH/AyZeCODZxC5E
9zH5tekaQLsEEVzQ87fgmyQz89vxxCyejODxU5HcLdo62BN38LytZhiQPI366KOA
vrS/k44ySDNa7oinvv2cE3X6T3s49P05QfcT4QIDAQABAoIBAQCV7JafzBT4tBtQ
nO3QkjNrShkUeqpw0lXBYBkZloHD51OOjIgwr4xqrYdAa8P4uCC7SiYyGn3g75bx
//n95TVqZaO1tt9CSlfuKqNa0GMxMwdREeB0vngtppbebAeSKWg6ppiC4kGy1D20
C+5giEdeg4FzJHBEJ5GmEFOi/HF3CdjynZkp0Exyur0NyFBNzt/5SA3g1/UVHu/l
FzxwzYhL5no8WagQyWzStMs577GkerFebv7vFqJhz/hrk8YZCT7WIZS+RW6xJKl5
ICClDColpOojPkEnEPzxnp8+RjKFjf29Z/hIF+Pd86gSyzDk+aH5kSOcXjuyyh/o
CbAJzPPxAoGBAMkkB+Lrn6kfj7o5zNMbe8P+9Q5IkmwOZSiOtwdQ3aONJWAdjpLY
eOk762RJTwOxVARfycvpgCS1MGReULtOU9vBFBdrKGblTxiusgu3q7/8RVREj3Ot
XP4Eqq3wHIQfAPS8d3iQs18OQ8vMnKkyredMkm4UhXjE6VXyFpUMhRotAoGBAMfn
gqZijKhmLtXWlYpNYIw6xPhGpVaH/dhGSoFc8XEcayC9Jt+BPhMt1U8YACNernwi
m5cR5z0Bh8Uld1gPPWNyMOVfGeuVMlY2y6vFOWLywXn+K1PJwyZkc0JnEg5uw5CN
C5w1hKDlk1D1ri1OrccmNkUfj0DEzsKvk2qrY3UFAoGAP1fwf98SXfGJku0m+wi5
tmSxifkC27LA2r/vFge6dQo7TgSg5M/1bAYpwGBx2Mjcm7AK3gPADk9dWQ52wDYP
pLIugJ2HkLgAa9aATb5fAUwSDVK2FojvMzQHCFYItPcKlwhPW5G+W14jrafXYlWK
fMAZkT83NWxVy3I8+F2EAVUCgYBI4sFBFxd/4tnav8WASpwUJO1iNKfd9/F25JIP
vqqNejYZFr5QqZfPeFuY3gBW5ROrURb3quBr3t345KMx6USRuLXZO6aAvcI/qvTx
qRQ2Xppqd2CmyR6tJdzcbiYoOvx0/OgpyV2VKH9g+mLKRDCaNvV8mHgrvlZAp7GR
J/I4XQKBgQCLkeHDNRO15TjqBBfTxzZFjoq7lYoj966QVhFONpG+seXsbGcswR2m
nVb1zInlKcpH9sSh7juMlOHvLKlCEwyPqNb00VBQH7XD4CgjdjsJ3kdaM57p0CFN
gRIb8XxxG6v5Q7AtgKYXyTqB4nn7lIPh/C4fuC5vXk2PdIKLGsukEw==
-----END RSA PRIVATE KEY-----

Make sure you have a blank line at the end of the file (and the certificate comes before the private key). You can download the pre-built certificate here https://tickett.net/downloads/netxms_ca.pem

Configuring the Certificate

  • Drop the ca.pem file anywhere on the NetXMS server
  • Modify netxmsd.conf and add the following lines;
ServerCACertificate = C:\NetXmsServer\etc\cert\ca.pem
ServerCertificate = C:\NetXmsServer\etc\cert\ca.pem
ServerCertificatePassword = netxms

Notice both the CACertificate and Certifcate path point to the same file. I don’t think the password is needed at all.

  • Restart the NetXMS Core service

Creating a Tunnel / Adding a WAN Node

  • Ensure your router is configured to forward traffic received on port 4703 to your NetXMS server
  • Ensure your NetXMS server firewall is configured to allow traffic in on port 4703
  • Modify your nxagentd.conf and add the following linse;
ServerConnection = server_wan_fqdn_or_ip
  • Restart NetXMS Agent service
  • In the NetXMS server, look under Configuration, Agent Tunnel Manager
  • You should see a red entry (if you don’t, something above went wrong)
  • Right click and select Create node and bind
  • Name your node and enter 0.0.0.0 for the ip/hostname and save (if the tunnel vanishes at this point, something above went wrong)

Good luck!

We have built a reporting tool for the Clover ePos which creates a text report for printing using the built-in receipt printer. The app has been through numerous iterations and the code which specifically handles alignment has always bugged me. The task seems trivial to the human mind, but when trying to code seems to throw a lot of curve balls! Here are some examples of the anticipated behavior;

alignment_examples

So we revisited it, and I hope have now built a simpler “one size fits all” (not exactly, but considerably less conditional than before). The code accepts a string with pipe separators to determine alignment (refer to the diagram above for a bit more info) and spits out a string padded accordingly;

public static string Align(string key, int width)
        {
            string newKey = "";
            string[] keyElements = key.Split('|');

            if (keyElements.Length == 1)
            {
                newKey += key;
            }
            else if (keyElements.Length == 2)
            {
                //left align the first chunk
                newKey += keyElements[0];
                //insert blank spaces so the entire line length will be a multiple of width
                newKey += new string('.', width - ((key.Length - 1) % width));
                //insert the last chunk
                newKey += keyElements[1];
            }
            else if (keyElements.Length == 3)
            {
                if (keyElements[0] != "")
                {
                    //left align the first chunk 
                    newKey += keyElements[0];
                    //and pad the rest of the line
                    newKey += new string('.', width - (keyElements[0].Length % width));
                }
                //pad the left, center the second chunk and pad the right
                double sidePadding = width - (keyElements[1].Length % width);
                int leftPadding = (int)Math.Floor(sidePadding / 2);
                int rightPadding = (int)Math.Ceiling(sidePadding / 2);
                newKey += new string('.', leftPadding) + keyElements[1] + new string('.', rightPadding);

                if (keyElements[2] != "")
                {
                    //pad the line
                    newKey += new string('.', width - (keyElements[2].Length % width));
                    //and right align the last chunk
                    newKey += keyElements[2];
                }
            }

            return newKey;
        }

The receipt printer automatically wraps the string but we use a small method to split the string into chunks and add carriage returns/new lines for ease of use. Initially, this too was cumbersome (with loops and ifs etc), but we found a more elegant solution (avoiding re-inventing the wheel and reducing the number of lines of code- though I appreciate a loop is still occurring under the hood);

        public static string Wrap(string key, int width)
        {
            return Regex.Replace(key, ".{" + width + "}", "$0" + Environment.NewLine);
        }

 

Here’s some code we used to test the method(s);

        static void Main(string[] args)
        {
            int width = 33;

            List keys = new List();
            keys.Add("Simple");
            keys.Add("The|quick");
            keys.Add("This first part is really long|quick");
            keys.Add("The|second part is ridiculously long");
            keys.Add("The|quick|brown");
            keys.Add("The centre segment will always sit on it's own line|quick|brown");

            foreach (string key in keys)
            {
                Console.WriteLine(new string('=', width));
                Console.WriteLine("Input: " + key);
                Console.WriteLine(new string('-', width));
                string aligned = Align(key, width);
                string wrapped = Wrap(aligned, width);
                Console.WriteLine(wrapped);
            }

            Console.ReadKey();
        }

Can you think of any further way we can simplify/improve the code?

We are in the process of trialling GitLab CE but need to tweak/customise a few elements.

Our developers are configured with the “developer permission/role” which unfortunately means they cannot create new projects. To get around this, we created a user/bot with the relevant permissions and a custom HTML page which uses the API to create a new project based on the user input.

I am not familiar with the ruby/slim syntax and struggled to modify the new project page as desired. We use GoogleTagManager fairly extensively in our work so decided it would probably be easiest to implement this throughout GitLab so our customisation could all be ring-fenced within GTM,

Adding GoogleTagManager to GitLab was fairly straight forward- adding 2 lines of code to;

 sudo nano /opt/gitlab/embedded/service/gitlab-rails/app/views/layouts/_head.html.haml

…below the %head tag, two %meta tags follow then we insert our javascript tag;

- page_description brand_title unless page_description

- site_name = "GitLab"
%head{ prefix: "og: http://ogp.me/ns#" }
  %meta{ charset: "utf-8" }
  %meta{ 'http-equiv' => 'X-UA-Compatible', content: 'IE=edge' }

  :javascript
    (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src='https://www.googletagmanager.co$

 

I have truncated the javascript- please ensure you paste the full code (from between the <script> tags presented by GoogleTagManager). Please also note the importance of the whitespace at the start of each line in the .haml file (the :javascript line should have 2 spaces before and the next line 4 spaces before).

I had to to issue a restart command to see the changes reflected in the front-end;

sudo gitlab-ctl restart

That’s it!

Do note that your changes may/will likely be lost if/when you update.

I hope we didn’t miss an obvious/easy/out of the box mechanism for adding GoogleTagManager to GitLab?

After just spending a few hours trying to get RedGate SQL Monitor to monitor our Windows 2016 SQL Server in AWS I though I better record the solution!

We already had a rule in place on the AWS firewall which should allow all traffic from our office so this was unlikely to be causing an issue.

We had enabled inbound rules in the windows firewall for RPC/WMI but to rule this out we disabled the firewall entirely (temporarily) which made no difference.

We tried connecting using the IP Address and hostname. Tried using .\username hostname\username, hostname.domain.name\username and received a variety of errors including;

Number: 0x80070776
Facility: Win32
Description: The object exporter specified was not found.

Number: 0x80070005
Facility: Win32
Description: Access is denied.

The end solution was adding a record to C:\windows\system32\drivers\etc\hosts with the public IP and hostname (not fully qualified). Then I was able to connect just fine using \\hostname\root\cimv2 with the username .\username

It seems to be a NAT related issue despite the AWS server having a public IP.

%d bloggers like this: