Saturday, 29 August 2020

CURL: The revocation function was unable to check revocation for the certificate

Two days ago I was trying to install Istio on a Minikube installation on my personal laptop. On Istio installation  documentation page they have a curl command to download the installation script for Istioctl. To my surprise the curl command that I use on Windows 10 showed the following error.
curl: (35) schannel: next InitializeSecurityContext failed: Unknown error (0x80092012) - The revocation function was unable to check revocation for the certificate.
Obviously this error is shown if the SSL certificate cannot be validated by curl, for example if the URL was serving a self signed certificate. But I was seeing this error when accessing a public URL.

I thought that may be curl executable that comes with Git for Windows that I used is out of date and doesn't work with the latest Windows 10 update. I went ahead and updated Git. But curl still didn't work.

Then I thought that may be there's an issue with the SSL configuration of the website (https://istio.io/downloadIstio) that I'm trying to access, but to my surprise, all HTTPS URLs that I tried to use were giving the same error.

I started suspecting the SSL certificates being served on my laptop. I have had some experience with MiTM attacks performed by intercepting HTTPS traffic. I have also seen this when working inside corporate networks, sometimes Root CA SSL certificates served inside corporate networks for public websites is not public CA certificate but owned and injected by the private company itself. This is probably done to scan HTTPS traffic coming inside the company network.

But here I was trying to do this on my personal laptop and I was not on corporate network. I suspected that it could be related to the VPN client that I was using, but stopping VPN client also didn't resolve the issue.

At this point, I was lost and had suspicions that my laptop had a good old virus.

Well I knew that browsers that I was using didn't have any issue opening these sites so I inspected the certificate details of https://google.com and here is what I saw.



As you can see root certificate chain doesn't look right. I indeed have Kaspersky antivirus installed on my laptop. After some googling I found that it's a standard practice among antiviruses to install a self signed CA root certificate on machines where they are running on. This CA certificate is then used by antiviruses to decrypt all HTTPs traffic to inspect for malware. Antiviruses claim that this CA certificate never leaves customer's machine so no one else is able to perform MiTM on the customer.

In my case this option in Kaspersky was enabled by default.

Here's the link to the stackexchange discussion on the same practice


I didn't want Kaspersky to inspect my SSL traffic, I know that it has as much control over my laptop as possible already but that's where I draw the line. It should not break my curl :)

Now I knew that I had to disable this setting in Kaspersky to get curl to work, but as always it's not easy to find.

After going through the settings for a few minutes I finally found it and I'm going to put the steps below.
  1. Click on the settings icon (gear icon at the bottom left corner)
  2. Click on the last option Additional
  3. Click on Network option
  4. And there's the option to disable HTTPS inspection


After doing this certificate details in browsers started looking ok for example, see the screeshot for https://google.com again. Most of all curl also started working.



Another day, another bug.

...till next time

Monday, 25 June 2018

Spring Boot /services endpoint weirdness (405 Method Not Allowed)

This was an error that I encountered a few years back and it's still alive and well to trap programmers who use this feature unknowingly.
I had following simple code in which first method /services_1 worked and /services didn't work. It simply returns 405 Method Not Allowed status with empty response.
@RestController
@RestController
class TestRest {
    @GetMapping("/services")
    public String test() {
        return "Hello World!";
    }
    @GetMapping("/services_1")
    public String test2() {
        return "Hello World!";
    }
}
So I started looking around and found that I had extra dependency in POM for web services, which was not being used and /services endpoint worked if I removed it. Following is the dependency in question
<dependency>
    <groupid>org.springframework.boot</groupid>
    <artifactid>spring-boot-starter-web-services</artifactid>
</dependency>
This is a dependency used for SOAP web services support in Spring Boot. But why would Spring stop /services from being accessed in presence of this dependency? I was sure at this point that there was probably an extra servlet loaded by Spring which was hogging all requests to /services and thus intended REST method was not being called.
After debugging further I decided to list all the Servlets registered by Spring Boot and print there url-mappings to find out offending servlet using following code
@Autowired
private List<ServletRegistrationBean> servlets;
...
for(ServletRegistrationBean servlet: servlets) {
    System.out.println(servlet.getServletName() + ": " + Arrays.toString(servlet.getUrlMappings().toArray()));
}
I know it's crude but it works. Following is the output that I got,
dispatcherServlet: [/]
messageDispatcherServlet: [/services/*]
So there's the extra messageDispatcherServlet that I didn't need and was overriding /services method declared by my REST class.
Now why does it happen? It's because messageDispatcherServlet's default url-mapping is done to /services.
It's done in following property configuration class
package org.springframework.boot.autoconfigure.webservices;
@ConfigurationProperties(prefix = "spring.webservices")
public class WebServicesProperties {
    /**
     * Path that serves as the base URI for the services.
     */
    private String path = "/services";
and used in following class
class: org.springframework.boot.autoconfigure.webservices.WebServicesAutoConfiguration

public class WebServicesAutoConfiguration {
    private final WebServicesProperties properties;

    @Bean
    public ServletRegistrationBean messageDispatcherServlet(
            ApplicationContext applicationContext) {
        MessageDispatcherServlet servlet = new MessageDispatcherServlet();
        servlet.setApplicationContext(applicationContext);
        String path = this.properties.getPath();
        String urlMapping = (path.endsWith("/") ? path + "*" : path + "/*");
        ServletRegistrationBean registration = new ServletRegistrationBean<>(
                servlet, urlMapping);
So that took a while to figure out, I must say a message or an error from Spring would have been nice and helpful to figure out what was going on.

...till next time

Sunday, 9 October 2016

Laptop screen colors too dark or red even at maximum brightness

This isn't a programming issue, I just want to make note of the solution that I found for future usage.

I had purchased an Acer laptop a few months back. I have experience with Dell laptops only where I didn't have to do any color calibration. It looked great from the first boot.

However with the Acer laptop I was able to see a significant issue with the screen colors to the point that it was unusable. Dark pixels when playing video were indistinguishable. To add to that screen seemed too red, like skin color was tinted dark unnatural red.

I thought this was due to the brightness setting however the issue persisted even after setting brightness to maximum. I also tried color calibration in Windows personalization settings, but it didn't work. I was convinced that issue was with brightness.

In the calibration settings we can see following image for brightness setting.



When opening this setting on the laptop with the issue in question background and person's coat won't be distinguishable.

I talked to the shop where I purchased the laptop from and they said this was an issue with Acer laptops, so I returned it and made a note to never buy an Acer laptop again.

Laptop had Windows 10 Home OS.

Then I purchased another laptop, it wasn't from Dell again. And I saw the same issue. However this laptop was too nice and I was determined to make it work.

So I finally found a solution after spending hours on the Internet searching for the issue.

The issue is with Gamma setting. This setting determines the maximum brightness of the laptop screen.



By default on Windows 10 its set in the middle of the slider. Which works for Dell laptop out of box without changing it.

However with laptops where default maximum brightness is not good enough this setting can be changed. So I pushed the gamma slider towards top and issue was resolved. This surprisingly also took care of the issue of too much red saturation in the images.

Friday, 25 March 2016

CXF Warning : class xyz has no JAX-RS Path or HTTP Method

Ok, it's been a long time. I have faced too many issues and got solutions for quite a few of them. I don't think I have time to log all of them properly so I'll just put them in minimum words here and if I ever get some time I'll properly format these entries.

I was working with CXF Rest services and I just could not figure out why my service was giving 404. Other service with virtually same configuration were working and some were giving flat out 404.

After taking a look at logs I found that for these services (404) there were entries like class xyz doesn't has no JAX-RS Path or HTTP Method.

I was trying to find the differences between the working and non working services. Every service had an interface and implementation class. Annotations were applied to the interfaces. Almost everything looked normal.

Then I finally saw that some of the JAX RS annotations were present in the implementation classes for the services giving 404. As soon as I removed them, Viola! it worked like magic.

After all this work and searching I was thinking why would you do this to me ( CXF ?).

As it turns out if a concrete REST class contains any REST annotations then it's super class/interface is not scanned for annotations.

I can almost swear that it worked for older versions of CXF, anyway all is well if it ends well.

CXF version used : 3.15

Thursday, 24 September 2015

Keyboard shortcuts and mouse functions for HTML 5 video

This time I was playing with HTML 5 video tag, but there are no keyboard shortcuts out of the box.
So I implemented a simple jQuery plugin.
Please find the link below:
https://github.com/ConsciousObserver/Html5VideoShortCutPlugin/blob/master/public/js/plugin/Html5VideoShortCutPlugin.js

I have implemented a few shortcuts which I use in VLC media player. Code can be easily extended without much fuss.
As of now following options are supported:

  1. Play/pause (spacebar and mouse click)
  2. Video navigation (10 seconds, 25 seconds, 40 seconds, left right arrows with ctrl or shift)
  3. Volume control (up and down arrows)
  4. Fast forward (+ key)
  5. Slow down (- key)
  6. Screenshot (shift + e)
Usage details can be found below:
https://github.com/ConsciousObserver/Html5VideoShortCutPlugin

Following is a working example:

Due to blogger trapping many events some shortcuts may not work here as expected, however you can use 'f' or press 'enter' to enter fullscreen mode. After that all shortcuts should work.

Friday, 18 September 2015

Bundle_xyz.jar does not have a META-INF/MANIFEST.MF! Make sure, META-INF and MANIFEST.MF are the first 2 entries in your JAR!

I encountered this during deployment of an OSGI bundle on Karaf.
I needed to change some configuration files in the bundle JAR file, so instead of rebuilding it, I just unpacked it on the remote server, modified the configuration and then archived it using ZIP tool.
After all, that's what I thought a JAR file was, a ZIP file. I had followed the same process hundreds of times on my local setup and had never gotten the error. I thought something was wrong with the server. I thought the user with which I had deployed the JAR and the user with which server process was running were two different users, and since server process did not have the access to the JAR deployed by me, it couldn't read it and hence the error. A well formed possible explanation to make the sense of the things again and leave the burden to someone else.
After a lot of searching and reading I found what was wrong.

JAR file is not a simple ZIP file.

When creating a ZIP file any tool/program simply follows it's own guideline for which entries should be made first in the archive file. Most of the times it would be in alphabetic order where directories appear first.
However in a valid JAR file order of entries is not as loosely defined as in a ZIP file. In a valid JAR file following should be the first 2 entries:

  1. META-INF/
  2. META-INF/MANIFEST.MF
After these 2 entries rest of entries can be in any order.
Entries in a JAR file can be printed using following command :
jar -tf Test.jar

For example running above command on commons-lang-2.6.jar prints following output (I have included only top few lines)

META-INF/
META-INF/MANIFEST.MF
org/
org/apache/
org/apache/commons/
org/apache/commons/lang/
org/apache/commons/lang/builder/
org/apache/commons/lang/enum/
org/apache/commons/lang/enums/
org/apache/commons/lang/exception/
org/apache/commons/lang/math/
org/apache/commons/lang/mutable/
org/apache/commons/lang/reflect/
org/apache/commons/lang/text/
org/apache/commons/lang/time/
META-INF/LICENSE.txt
META-INF/NOTICE.txt

As you can see first two entries are META-INF/ and META-INF/MANIFEST.MF.

After getting this information, solution is obvious, just build the JAR using the build process that you are using and then deploy it on server.

This rule of first two fixed entries is ignored by many containers but we never know which one will enforce it. Safest way is to manipulate JAR file using the tools provided by the JDK.
The same rule seems to be true for WAR file also, but I have yet to encounter an application server which enforces it.

...till next time

Wednesday, 16 September 2015

Spring OSGI bundle, how does Karaf know where to get the bean configuration files

I have been working with some OSGI based applications and they are deployed on the OSGI container Karaf. I know I should have looked it up earlier however I recently realized I did not know how the Karaf knew where it could find my bean configuration files. I looked around and found out the answer.
Quick answer is below and for more keep reading.
Karaf looks at two places to get the clue of where the bean configuration files are :

  1. META-INF/MANIFEST.MF (if Spring-Context attribute is present)
  2. META-INF/spring (if it contains XML files)
To be able to load an Spring application Karaf needs a feature called Spring Dynamic Modules or in short Spring DM. To query the list of the features you can run

features:list

Or some combination of the same command (I'm using Talend Karaf runtime).

Spring-DM feature loads following bundles
  • org.springframeork.osgi.bundle.extender
  • org.springframeork.osgi.bundle.core
  • org.springframeork.osgi.bundle.io
org.springframeork.osgi.bundle.extender keeps on querying the OSGI container for the newly loaded bundles to see if they are powered by Spring. It checks first the Spring-Context attribute in META-INF/MANIFEST.MF if not present it checks the META-INF/spring for XML files.
When bundles containing the configuration files are found, it simply initializes the Spring Context.

I found this information on an old entry on Javaworld
Introduction to Spring Dynamic Modules

Though old information here is still relevant and true. Spring DM in all likelihood is probably dead and it is succeeded by Eclipse Gemini Blueprint.
Follow the links for more info :
Spring Dynamic Modules becomes Eclipse Gemini Blueprint
relationship between Spring Dynamic Modules and Gemini Blueprint

However even after all this time Spring-DM can be seen at work in many places and it still works fine out of the box.