You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@guacamole.apache.org by Passerini Marco <ma...@cscs.ch> on 2021/04/22 10:24:42 UTC

Can't create new connections with Guacamole REST API

Hi,


I made a python script which authenticates against my Guacamole instance as guacadmin, lists existing connections and creates a new one. Authentication and listing works fine, meanwhile creation does not work.

I used this API specification: https://github.com/ridvanaltun/guacamole-rest-api-documentation/blob/master/docs/CONNECTIONS.md#create-ssh-connection

However the API documentation seems to be for 1.1.0 and I'm using 1.3.0. I couldn't find anything more recent.

Am I missing some parameter? Where can I find a more recent documentation?

The logged error is not very clear:


"org.codehaus.jackson.map.JsonMappingException: Can not instantiate value of type [simple type, class org.apache.guacamole.rest.connection.APIConnection] from JSON String; no single-String constructor/factory method"




######################################

import requests
from requests.auth import HTTPBasicAuth
import simplejson

# authenticate
password = ""
with open('guacamole_password', "r") as fd:
    password = fd.readline().rstrip()

result = requests.post('http://*****myserver******:8080/guacamole-1.3.0/api/tokens', auth=HTTPBasicAuth('guacadmin', password), verify=False)

auth_token = result.json()['authToken']
data_source = result.json()['dataSource']

# list the existing connections
params = {'token': auth_token}
response = requests.get('http://*****myserver******8080/guacamole-1.3.0/api/session/data/'+data_source+'/connections', params=params, verify=False)
print(response.json())


data = {
      "parentIdentifier": "ROOT",
      "name": "pythontest",
      "protocol": "ssh",
      "parameters": {
        "port": "22",
        "read-only": "",
        "swap-red-blue": "",
        "cursor": "",
        "color-depth": "",
        "clipboard-encoding": "",
        "disable-copy": "",
        "disable-paste": "",
        "dest-port": "",
        "recording-exclude-output": "",
        "recording-exclude-mouse": "",
        "recording-include-keys": "",
        "create-recording-path": "",
        "enable-sftp": "",
        "sftp-port": "",
        "sftp-server-alive-interval": "",
        "enable-audio": "",
        "color-scheme": "",
        "font-size": "",
        "scrollback": "",
        "timezone": "",
        "server-alive-interval": "",
        "backspace": "",
        "terminal-type": "",
        "create-typescript-path": "",
        "hostname": "148.187.98.221",
        "host-key": "",
        "private-key": "",
        "username": "testuser",
        "password": "testpassword",
        "passphrase": "",
        "font-name": "",
        "command": "",
        "locale": "",
        "typescript-path": "",
        "typescript-name": "",
        "recording-path": "",
        "recording-name": "",
        "sftp-root-directory": ""
      },
      "attributes": {
        "max-connections": "",
        "max-connections-per-user": "",
        "weight": "",
        "failover-only": "",
        "guacd-port": "",
        "guacd-encryption": "",
        "guacd-hostname": ""
      }
    }


data_json = simplejson.dumps(data)
headers = {'Content-type': 'application/json'}
response = requests.post('http://*****myserver******:8080/guacamole-1.3.0/api/session/data/'+data_source+'/connections', params=params, json=data_json, verify=False, headers=headers)
print(response.json())
######################################



######################################
(myenv) [flaskapp@mfa-oidc-test2 mfa_app]$ python guacamole_client.py
{}
{'message': 'Unexpected internal error', 'translatableMessage': {'key': 'APP.TEXT_UNTRANSLATED', 'variables': {'MESSAGE': 'Unexpected internal error'}}, 'statusCode': None, 'expected': None, 'type': 'INTERNAL_ERROR'}


######################################




######################################
Apr 22 12:17:00 mfa-guacamole server: 12:17:00.592 [http-bio-8080-exec-14] INFO  o.a.g.r.auth.AuthenticationService - User "guacadmin" successfully authenticated from 148.187.80.37.
Apr 22 12:17:00 mfa-guacamole server: 12:17:00.607 [http-bio-8080-exec-14] DEBUG o.a.g.r.auth.AuthenticationService - Login was successful for user "guacadmin".
Apr 22 12:17:00 mfa-guacamole server: 12:17:00.628 [http-bio-8080-exec-13] ERROR o.a.g.rest.RESTExceptionMapper - Unexpected internal error: Can not instantiate value of type [simple type, class org.apache.guacamole.rest.connection.APIConnection] from JSON String; no single-String constructor/factory method
Apr 22 12:17:00 mfa-guacamole server: 12:17:00.629 [http-bio-8080-exec-13] DEBUG o.a.g.rest.RESTExceptionMapper - Unexpected error in REST endpoint.
Apr 22 12:17:00 mfa-guacamole server: org.codehaus.jackson.map.JsonMappingException: Can not instantiate value of type [simple type, class org.apache.guacamole.rest.connection.APIConnection] from JSON String; no single-String constructor/factory method
Apr 22 12:17:00 mfa-guacamole server: at org.codehaus.jackson.map.deser.std.StdValueInstantiator._createFromStringFallbacks(StdValueInstantiator.java:379)
Apr 22 12:17:00 mfa-guacamole server: at org.codehaus.jackson.map.deser.std.StdValueInstantiator.createFromString(StdValueInstantiator.java:268)
Apr 22 12:17:00 mfa-guacamole server: at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeFromString(BeanDeserializer.java:759)
Apr 22 12:17:00 mfa-guacamole server: at org.codehaus.jackson.map.deser.BeanDeserializer.deserialize(BeanDeserializer.java:585)
Apr 22 12:17:00 mfa-guacamole server: at org.codehaus.jackson.map.ObjectMapper._readValue(ObjectMapper.java:2695)
Apr 22 12:17:00 mfa-guacamole server: at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:1308)
Apr 22 12:17:00 mfa-guacamole server: at org.codehaus.jackson.jaxrs.JacksonJsonProvider.readFrom(JacksonJsonProvider.java:419)
Apr 22 12:17:00 mfa-guacamole server: at com.sun.jersey.spi.container.ContainerRequest.getEntity(ContainerRequest.java:488)
Apr 22 12:17:00 mfa-guacamole server: at com.sun.jersey.server.impl.model.method.dispatch.EntityParamDispatchProvider$EntityInjectable.getValue(EntityParamDispatchProvider.java:123)
Apr 22 12:17:00 mfa-guacamole server: at com.sun.jersey.server.impl.inject.InjectableValuesProvider.getInjectableValues(InjectableValuesProvider.java:46)
Apr 22 12:17:00 mfa-guacamole server: at com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$EntityParamInInvoker.getParams(AbstractResourceMethodDispatchProvider.java:153)
Apr 22 12:17:00 mfa-guacamole server: at com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$TypeOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:183)
Apr 22 12:17:00 mfa-guacamole server: at com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:75)
Apr 22 12:17:00 mfa-guacamole server: at com.sun.jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:302)
Apr 22 12:17:00 mfa-guacamole server: at com.sun.jersey.server.impl.uri.rules.SubLocatorRule.accept(SubLocatorRule.java:137)
Apr 22 12:17:00 mfa-guacamole server: at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
Apr 22 12:17:00 mfa-guacamole server: at com.sun.jersey.server.impl.uri.rules.SubLocatorRule.accept(SubLocatorRule.java:137)
Apr 22 12:17:00 mfa-guacamole server: at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
Apr 22 12:17:00 mfa-guacamole server: at com.sun.jersey.server.impl.uri.rules.SubLocatorRule.accept(SubLocatorRule.java:137)
Apr 22 12:17:00 mfa-guacamole server: at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
Apr 22 12:17:00 mfa-guacamole server: at com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:108)
Apr 22 12:17:00 mfa-guacamole server: at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
Apr 22 12:17:00 mfa-guacamole server: at com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:84)
Apr 22 12:17:00 mfa-guacamole server: at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1511)
Apr 22 12:17:00 mfa-guacamole server: at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1442)
Apr 22 12:17:00 mfa-guacamole server: at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1391)
Apr 22 12:17:00 mfa-guacamole server: at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1381)
Apr 22 12:17:00 mfa-guacamole server: at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:416)
Apr 22 12:17:00 mfa-guacamole server: at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:538)
Apr 22 12:17:00 mfa-guacamole server: at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:716)
Apr 22 12:17:00 mfa-guacamole server: at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
Apr 22 12:17:00 mfa-guacamole server: at com.google.inject.servlet.ServletDefinition.doService(ServletDefinition.java:263)
Apr 22 12:17:00 mfa-guacamole server: at com.google.inject.servlet.ServletDefinition.service(ServletDefinition.java:178)
Apr 22 12:17:00 mfa-guacamole server: at com.google.inject.servlet.ManagedServletPipeline.service(ManagedServletPipeline.java:91)
Apr 22 12:17:00 mfa-guacamole server: at com.google.inject.servlet.FilterChainInvocation.doFilter(FilterChainInvocation.java:62)
Apr 22 12:17:00 mfa-guacamole server: at com.google.inject.servlet.ManagedFilterPipeline.dispatch(ManagedFilterPipeline.java:118)
Apr 22 12:17:00 mfa-guacamole server: at com.google.inject.servlet.GuiceFilter.doFilter(GuiceFilter.java:113)
Apr 22 12:17:00 mfa-guacamole server: at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
Apr 22 12:17:00 mfa-guacamole server: at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
Apr 22 12:17:00 mfa-guacamole server: at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:218)
Apr 22 12:17:00 mfa-guacamole server: at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:110)
Apr 22 12:17:00 mfa-guacamole server: at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:498)
Apr 22 12:17:00 mfa-guacamole server: at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:169)
Apr 22 12:17:00 mfa-guacamole server: at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
Apr 22 12:17:00 mfa-guacamole server: at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:962)
Apr 22 12:17:00 mfa-guacamole server: at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
Apr 22 12:17:00 mfa-guacamole server: at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:445)
Apr 22 12:17:00 mfa-guacamole server: at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091)
Apr 22 12:17:00 mfa-guacamole server: at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:637)
Apr 22 12:17:00 mfa-guacamole server: at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
Apr 22 12:17:00 mfa-guacamole server: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
Apr 22 12:17:00 mfa-guacamole server: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
Apr 22 12:17:00 mfa-guacamole server: at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
Apr 22 12:17:00 mfa-guacamole server: at java.lang.Thread.run(Thread.java:748)
#######################

Regards,
Marco Passerini



Re: Can't create new connections with Guacamole REST API

Posted by Mike Jumper <mi...@glyptodon.com>.
On Thu, Apr 22, 2021 at 4:15 AM Nick Couchman <vn...@apache.org> wrote:

> On Thu, Apr 22, 2021 at 6:24 AM Passerini Marco <ma...@cscs.ch>
> wrote:
>
>> ...
>>
> The logged error is not very clear:
>>
>> "org.codehaus.jackson.map.JsonMappingException: Can not instantiate value
>> of type [simple type, class
>> org.apache.guacamole.rest.connection.APIConnection] from JSON String; no
>> single-String constructor/factory method"
>>
> That is a obscure error - it indicates to me that something in the data
> you've provided is not the format it is expecting.
>

Marco - I recommend capturing the raw HTTP traffic between your script and
Guacamole to see what is sent. It may be that the JSON is not actually
being formatted as expected, and that the data in the request body is
somehow not a proper JSON object.

Michael Jumper
CEO, Lead Developer
Glyptodon Inc <https://glyp.to/>.

Re: Can't create new connections with Guacamole REST API

Posted by Nick Couchman <vn...@apache.org>.
On Thu, Apr 22, 2021 at 6:24 AM Passerini Marco <ma...@cscs.ch>
wrote:

> Hi,
>
>
> I made a python script which authenticates against my Guacamole instance
> as guacadmin, lists existing connections and creates a new one.
> Authentication and listing works fine, meanwhile creation does not work.
>
> I used this API specification:
> https://github.com/ridvanaltun/guacamole-rest-api-documentation/blob/master/docs/CONNECTIONS.md#create-ssh-connection
>
> However the API documentation seems to be for 1.1.0 and I'm using 1.3.0.
> I couldn't find anything more recent.
>
Am I missing some parameter? Where can I find a more recent documentation?
>

At the moment the project does not have any official REST API
documentation. There are a couple of efforts going on to produce that
documentation, but nothing, yet. So, if someone has documented it (as
above), great, but it may not match up with the latest and greatest. That
said, I don't think much changed between 1.1.0 and 1.3.0 from the REST API
perspective, so, for the purposes of what you're doing, I don't think it
should matter much.


> The logged error is not very clear:
>
>
> "org.codehaus.jackson.map.JsonMappingException: Can not instantiate value
> of type [simple type, class
> org.apache.guacamole.rest.connection.APIConnection] from JSON String; no
> single-String constructor/factory method"
>
>
> That is a obscure error - it indicates to me that something in the data
you've provided is not the format it is expecting.


>
>
> ######################################
>
> import requests
> from requests.auth import HTTPBasicAuth
> import simplejson
>
> # authenticate
> password = ""
> with open('guacamole_password', "r") as fd:
>     password = fd.readline().rstrip()
>
> result = requests.post('http://*****myserver******:8080/guacamole-1.3.0/api/tokens',
> auth=HTTPBasicAuth('guacadmin', password), verify=False)
>
> auth_token = result.json()['authToken']
> data_source = result.json()['dataSource']
>
> # list the existing connections
> params = {'token': auth_token}
> response = requests.get('http://*****myserver******8080/guacamole-1.3.0/api/session/data/'+data_source+'/connections',
> params=params, verify=False)
> print(response.json())
>
>
> data = {
>       "parentIdentifier": "ROOT",
>       "name": "pythontest",
>       "protocol": "ssh",
>       "parameters": {
>         "port": "22",
>         "read-only": "",
>         "swap-red-blue": "",
>         "cursor": "",
>         "color-depth": "",
>         "clipboard-encoding": "",
>         "disable-copy": "",
>         "disable-paste": "",
>         "dest-port": "",
>         "recording-exclude-output": "",
>         "recording-exclude-mouse": "",
>         "recording-include-keys": "",
>         "create-recording-path": "",
>         "enable-sftp": "",
>         "sftp-port": "",
>         "sftp-server-alive-interval": "",
>         "enable-audio": "",
>         "color-scheme": "",
>         "font-size": "",
>         "scrollback": "",
>         "timezone": "",
>         "server-alive-interval": "",
>         "backspace": "",
>         "terminal-type": "",
>         "create-typescript-path": "",
>         "hostname": "148.187.98.221",
>         "host-key": "",
>         "private-key": "",
>         "username": "testuser",
>         "password": "testpassword",
>         "passphrase": "",
>         "font-name": "",
>         "command": "",
>         "locale": "",
>         "typescript-path": "",
>         "typescript-name": "",
>         "recording-path": "",
>         "recording-name": "",
>         "sftp-root-directory": ""
>       },
>       "attributes": {
>         "max-connections": "",
>         "max-connections-per-user": "",
>         "weight": "",
>         "failover-only": "",
>         "guacd-port": "",
>         "guacd-encryption": "",
>         "guacd-hostname": ""
>       }
>     }
>
>
First thing I'd say is you should remove any parameters that you're setting
to empty values, unless you actually want an empty value. Otherwise you're
just needlessly complicating the code. You do not have to provide a value
for every parameter - just the ones you want to have something other than
the default, which is NULL or False.


>
> data_json = simplejson.dumps(data)
> headers = {'Content-type': 'application/json'}
> response = requests.post('http://*****myserver******:8080/guacamole-1.3.0/api/session/data/'+data_source+'/connections',
> params=params, json=data_json, verify=False, headers=headers)
>

If I'm reading the Python Requests documentation directly, when you're
using "json=data_json" in the post request, you actually do not want to do
the "simplejson.dumps(data)" call. The "data" field already contains strict
JSON data, and the json= parameter within requests.post is meant to send
that directly without form encoding it. Have you tried just passing
"json=data", bypassing the simplejson.dumps call?

I'm honestly a little out of my league with this - I'm not all that
familiar with Python, particularly the requests library, but that's really
the only thing I can see.

-Nick

>