You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cloudstack.apache.org by yao hu <hu...@gmail.com> on 2013/10/22 05:24:28 UTC

access instance's console using apikey failed

I compiled cloudstack 4.1.1 source code in cygwin, then test it using
jetty, it works fine. But, when I access instance's console through vnc
using apikey, it fails, the browser shows the follow message:
Access denied. Invalid web session or API key in request

my url:
http://localhost:8080/client/console?cmd=access&vm=b194369f-e0d4-45d8-a50f-09ec51095e68&apikey=fmS7oyThP6MGxN5X_CgeOCxQIqgTu5QFDz46r2Pv5kLp88EYYBquSu6_3s3d9MXdbUHPpxj5qDDy1jvhEpQWvQ&signature=y3dNHn580NJiCVRGwrBTR4JHImo%3D

I test the listAccounts api, it's ok.
my url:
http://localhost:8080/client/api?command=listAccounts&apikey=fmS7oyThP6MGxN5X_CgeOCxQIqgTu5QFDz46r2Pv5kLp88EYYBquSu6_3s3d9MXdbUHPpxj5qDDy1jvhEpQWvQ&signature=ALhJtw%2Bzi7Rcmo%2Bkk3xH3cTJgp4%3D

then, I debug the source code, find where it fails.
file: ConsoleProxyServlet.java
private boolean verifyRequest(Map<String, Object[]> requestParameters) {
try {
...
...

unsignedRequest = unsignedRequest.toLowerCase();

Mac mac = Mac.getInstance("HmacSHA1");
SecretKeySpec keySpec = new SecretKeySpec(secretKey.getBytes(),
"HmacSHA1");
mac.init(keySpec);
mac.update(unsignedRequest.getBytes());
byte[] encryptedBytes = mac.doFinal();
String computedSignature =
Base64.encodeBase64URLSafeString(encryptedBytes);
boolean equalSig = signature.equals(computedSignature);
if (!equalSig) {
s_logger.debug("User signature: " + signature + " is not equaled to
computed signature: " + computedSignature);
}
...
...
return equalSig;
} catch (Exception ex) {
s_logger.error("unable to verifty request signature", ex);
}
return false;
}

in this method, signature not equals to computedSignature, so it returns
false


then, I view ApiServer.javaļ¼Œthe verifyRequest method:
public boolean verifyRequest(Map<String, Object[]> requestParameters, Long
userId) throws ServerApiException {
try {
...
...

unsignedRequest = unsignedRequest.toLowerCase();

Mac mac = Mac.getInstance("HmacSHA1");
SecretKeySpec keySpec = new SecretKeySpec(secretKey.getBytes(),
"HmacSHA1");
mac.init(keySpec);
mac.update(unsignedRequest.getBytes());
byte[] encryptedBytes = mac.doFinal();
String computedSignature = Base64.encodeBase64String(encryptedBytes);
boolean equalSig = signature.equals(computedSignature);
if (!equalSig) {
s_logger.debug("User signature: " + signature + " is not equaled to
computed signature: " + computedSignature);
}
...
...
return equalSig;
} catch (Exception ex) {
s_logger.error("unable to verifty request signature", ex);
}
return false;
}

these two verifyRequest method produce different signature, because the
former use :
String computedSignature =
Base64.encodeBase64URLSafeString(encryptedBytes);

while the later use:
String computedSignature = Base64.encodeBase64String(encryptedBytes);

this is why listAccouts works fine, but vnc console is failed.

when I replace Base64.encodeBase64URLSafeString by
Base64.encodeBase64String, vnc console is ok too.


so I am confused, why use different encode method? It is a bug?