Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

3.0.0 #658

Closed
wants to merge 50 commits into from
Closed

3.0.0 #658

wants to merge 50 commits into from

Conversation

JamesJeffryes and others added 30 commits September 23, 2020 10:33
Update from ubuntu xenial(16.04) to bionic(18.04)
Mentioned issue in #544
Try to make python 3.7 standard on osx
Drop python 2 from travis.sh
Try fixing osx to get python installed...
…nted python3 while installing package dependencies
Use async/await keywords in test_server_asyncio.py
Set "strict" to False since it mailfunctions
This patch adds server requiring client's certificate feature which is
mentioned in the 6th step CertificateRequest to 9th step
VerifyClientCertSig in Table 5 TLS Full Handshake Protocol of MODBUS/TCP
Security Protocol Specification [1].

This patch implements the feature within both sync and async_io version.

* Server side:
Add an optional argument "reqclicert" of StartTlsServer(). So, users can
force server require client's certificate for TLS full handshake, or
according to the SSL Context's original behavior [2].

* Client side:
Add optional arguments "certfile" and "keyfile" for replying, if the
server requires client's certificate for TLS full handshake.

Besides, also add an optional argument "password" on both server and
client side for decrypting the private keyfile.

This fixes part of #606

[1]: http://modbus.org/docs/MB-TCP-Security-v21_2018-07-24.pdf
[2]: https://docs.python.org/3/library/ssl.html#ssl.SSLContext.verify_mode
@dhoomakethu
Copy link
Contributor Author

If you think some of the changes from the PR's are not merged correctly or have been overidden by subsequent merges, please raise a new PR against 3.0.0 branch

@dhoomakethu dhoomakethu mentioned this pull request Aug 1, 2021
@dhoomakethu
Copy link
Contributor Author

@starnight please take a look in to this PR

@starnight
Copy link
Contributor

Have a PR #661 to fix the conflicts. @dhoomakethu please take a look.

Developers add/fix features at the same time, then produce the conflicts
in pymodbus' TLS module. This patch tries to fix the conflicts.
@sonarqubecloud
Copy link

sonarqubecloud bot commented Aug 9, 2021

SonarCloud Quality Gate failed.    Quality Gate failed

Bug E 5 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot E 3 Security Hotspots
Code Smell A 7 Code Smells

No Coverage information No Coverage information
3.8% 3.8% Duplication

@github-actions
Copy link

This PR is stale because it has been open 45 days with no activity. Remove stale label or comment or this will be closed in 10 days.

@@ -103,11 +108,12 @@ def async_io_factory(port=None, framer=None, **kwargs):

client = AsyncioModbusSerialClient(port, proto_cls, framer, loop, **kwargs)
coro = client.connect()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This coroutine is never awaited if the following is true: loop.is_running() and loop is asyncio.get_event_loop()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Proposed fixes if you create from within another coroutine,- option 3 seems the cleanest!

option 1

inside the factory, create the task and return

   coro = client.connect()
   if loop.is_running() and loop is asyncio.get_event_loop():
        asyncio.create_task(coro)
        return loop, client

the the caller should just pause its execution to allow the connect schedule on the event loop to complete

async def main():
    _loop, client = AsyncSerialClient(...)
    asyncio.sleep(0)  # this allows this excution to wait 

option 2

from the factory, return the coro and client (instead of the loop - here the signature is different)

   coro = client.connect()
   if loop.is_running() and loop is asyncio.get_event_loop():
        return coro, client

the the caller you can then await the coro

async def main():
    coro, client = AsyncSerialClient(...)
    await coro

option 3

inside the factory, dont create the coro

    # coro = client.connect()
    if loop.is_running() and loop is asyncio.get_event_loop():
        return coro, client
   
    coro = client.connect()

the the caller you can then await client.connect()

async def main():
    loop, client = AsyncSerialClient(...)
    await client.connect()

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem with asyncio code is not most of the users will be knowing how to use it and end up creating more tickets. I will see what could be done. Thanks for the suggestion.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, that makes option 1&2 above rather cryptic.

My suggestion would be NOT to connect during the creation, but always leave it to the user to call client.connect()

Then they can do either one of the following, depending on where they start it from

loop, client = AsyncSerialClient(...)

# Option a - Loop has yet to start
asyncio.run_until_complete(client.connect())

# Option b - if the loop is already running and they are inside a coroutine/async def function
await client.connect()

# Option c - from python 3.7 replaces the ensure_future code currently there..
# although this works from a running coroutine, you might have to await it, so awaiting the client.connect (option a) is better)
asyncio.create_task(client.connect())

Copy link

@kellerza kellerza Sep 30, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think #558 was an attempt to fix this for TCP. In that case they also left client.connect() to the caller, but this was not clearly mentioned in the PR

Also, you really want to same interface, irrespective of where you call things from. So believe splitting out the connect is the way to go. Let me know if you want me to do a PR in the 3.0.0 branch (its not clear when/if you will merge this PR?)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good question, it was supposed to be merged and available a long time ago but due to time constraints and the pandemic this is getting nowhere. I have no idea of the timeline but I am hopeful to get a 3.x release by the end of year.

* Replace distutils.version.Looseversion with pcg_resources.parse_version

* Replace distutils.core.Command with setuptools.Command
@sonarqubecloud
Copy link

SonarCloud Quality Gate failed.    Quality Gate failed

Bug E 5 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot E 3 Security Hotspots
Code Smell A 7 Code Smells

No Coverage information No Coverage information
3.5% 3.5% Duplication

@github-actions
Copy link

github-actions bot commented Dec 2, 2021

This PR is stale because it has been open 45 days with no activity. Remove stale label or comment or this will be closed in 10 days.

@github-actions
Copy link

This PR was closed because it has been stalled for 10 days with no activity.

@github-actions github-actions bot closed this Dec 12, 2021
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 21, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants