Hi Rick, as mentioned in your thread on the dev mailing list [1], in
the above code your server isn't listening using TLS and your client
isn't trying to connect over TLS. This has to do with how you're
constructing your locations for each.

In your server code, use flight.Location.for_grpc_tls instead of
flight.Location.for_grpc_tcp to enable TLS. Once you make this change,
you should get an error on startup about your invalid certs. As
mentioned [1], some input validation could be added and this would
likely be a welcome contribution [3].

In your client code, you'll then need to change
"grpc://localhost:8081" to "grpc+tls://localhost:8081" (note the
"grpc+tls+ scheme) or use flight.Location.for_grpc_tls like in the
server.

See the Python cookbook [4] for a complete example. Hope that helps.

[1] https://lists.apache.org/thread/d7nh0s2g80358ws2phtl6hzsnw0xlrdy
[2] 
https://arrow.apache.org/docs/python/generated/pyarrow.flight.Location.html#pyarrow.flight.Location.for_grpc_tls
[3] https://arrow.apache.org/docs/developers/guide/index.html
[4] 
https://arrow.apache.org/cookbook/py/flight.html#securing-connections-with-tls

On Thu, Jan 4, 2024 at 3:24 AM Rick Spencer
<[email protected]> wrote:
>
> I am working on supporting TLS, and it looks like everything that I need is 
> built into FlightServerBase.
>
> However, I am struggling to understand how it works, or how to test that it 
> is working. For example, I don't understand why I can pass garbage in for the 
> tls_certs, and still get results when called from a client. Here is a minimal 
> example I put together to show where I am confused.
>
> Server that I think should not work:
> ```python
> from pyarrow import flight, Table
>
> class SampleServer(flight.FlightServerBase):
>     def __init__(self, *args, **kwargs):
>         tls_certificates = [("garbage", "garbage")]
>         location = flight.Location.for_grpc_tcp("localhost", 8081)
>         super(SampleServer, self).__init__(location,
>                                            None,
>                                            tls_certificates,
>                                            False,
>                                            None,
>                                            *args, **kwargs)
>
>     def do_get(self, context, ticket):
>         data = {'col': [1]}
>         table = Table.from_pydict(data)
>         return flight.RecordBatchStream(table)
>
> if __name__ == "__main__":
>     server = SampleServer()
>     server.serve()
> ```
>
> Client code that I think should not work:
> ```python
> import pyarrow.flight as fl
> import json
> def main():
>     server_location = "grpc://localhost:8081"
>
>     client = fl.FlightClient(server_location)
>     ticket = fl.Ticket(json.dumps({}))
>     reader = client.do_get(ticket)
>     print(reader.read_all().to_pandas())
>
> if __name__ == "__main__":
>     main()
> ```
>
> But when I run the server, and then the client, I get a result:
>
> ```
> % python3 client.py
>    col
> 0    1
> ```
>
> I would expect some kind of TLS error.
>
> I am sure that I am confused about something, but if someone could help me 
> with my reasoning, I would appreciate it.
>
> For reference, my project is here: https://github.com/rickspencer3/shoots

Reply via email to