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

SNOW-1502056: using connections.toml always returns a "Bad owner or permissions" on UserWarning #1978

Open
patrickhowerter opened this issue Jun 24, 2024 · 4 comments
Assignees
Labels
bug status-triage_done Initial triage done, will be further handled by the driver team

Comments

@patrickhowerter
Copy link

Python version

Python 3.11.8

Operating system and processor architecture

Windows-10-10.0.19045-SP0

Installed packages

annotated-types==0.6.0
asn1crypto==1.5.1
atpublic==4.1.0
attrs==23.2.0
azure-core==1.30.1
azure-storage-blob==12.19.1
certifi==2024.6.2
cffi==1.16.0
charset-normalizer==3.3.2
cloudpickle==2.2.1
colorama==0.4.6
coverage==7.5.0
cryptography==42.0.8
dill==0.3.8
filelock==3.15.3
fsspec==2024.6.0
idna==3.7
importlib_metadata==7.1.0
importlib_resources==6.4.0
iniconfig==2.0.0
isodate==0.6.1
jaraco.classes==3.4.0
keyring==24.3.1
modin==0.28.1
more-itertools==10.2.0
numpy==1.26.4
packaging==24.1
pandas==2.2.1
platformdirs==4.2.2
pluggy==1.5.0
psutil==5.9.8
pyarrow==16.1.0
pycparser==2.22
pydantic==2.7.0
python-dateutil==2.9.0.post0
pytz==2024.1
pywin32-ctypes==0.2.2
PyYAML==6.0.1
requests==2.32.3
six==1.16.0
snowflake==0.8.1
snowflake-connector-python==3.11.0
snowflake-snowpark-python==1.18.0
snowflake._legacy==0.7.0
snowflake.core==0.8.1
sortedcontainers==2.4.0
tomlkit==0.12.5
typing_extensions==4.12.2
tzdata==2024.1
urllib3==2.2.2
zipp==3.18.1

What did you do?

I created a connection.toml file. Then changed the permissions so that the user is the only user with read-write permissions.  I still return this warning message:

import snowflake.snowpark as sp
session = sp.Session.builder.config('connection_name', 'mdo').create()

D:\mdo.snow\python_files\mdosdkenv\Lib\site-packages\snowflake\connector\config_manager.py:351: UserWarning: Bad owner or permissions on C:\Users\patri\AppData\Local\snowflake\connections.toml
  warn(f"Bad owner or permissions on {str(filep)}{chmod_message}")

What did you expect to see?

I expect to see no warning messages.

Can you set logging to DEBUG and collect the logs?

yes, here is the output:

D:\mdo.snow\python_files\mdosdkenv\Lib\site-packages\snowflake\connector\config_manager.py:351: UserWarning: Bad owner or permissions on C:\Users\patri\AppData\Local\snowflake\connections.toml
  warn(f"Bad owner or permissions on {str(filep)}{chmod_message}")
2024-06-24 09:38:28,865 - MainThread config_manager.py:352 - read_config() - DEBUG - reading configuration file from C:\Users\patri\AppData\Local\snowflake\connections.toml
2024-06-24 09:38:28,867 - MainThread connection.py:408 - __init__() - INFO - Snowflake Connector for Python Version: 3.11.0, Python Version: 3.11.8, Platform: Windows-10-10.0.19045-SP0
2024-06-24 09:38:28,868 - MainThread connection.py:714 - connect() - DEBUG - connect
2024-06-24 09:38:28,868 - MainThread connection.py:1099 - __config() - DEBUG - __config
2024-06-24 09:38:28,868 - MainThread connection.py:1258 - __config() - INFO - This connection is in OCSP Fail Open Mode. TLS Certificates would be checked for validity and revocation status. Any other Certificate Revocation related exceptions or OCSP Responder failures would be disregarded in favor of connectivity.
2024-06-24 09:38:28,868 - MainThread converter.py:159 - __init__() - DEBUG - use_numpy: False
2024-06-24 09:38:28,868 - MainThread converter_issue23517.py:27 - __init__() - DEBUG - initialized
2024-06-24 09:38:28,868 - MainThread connection.py:926 - __open_connection() - DEBUG - REST API object was created: kub99688.us-east-1.snowflakecomputing.com:443
2024-06-24 09:38:28,869 - MainThread _auth.py:174 - authenticate() - DEBUG - authenticate
2024-06-24 09:38:28,870 - MainThread _auth.py:208 - authenticate() - DEBUG - assertion content: ver:1-hint:5473948711610254-hiding
2024-06-24 09:38:28,870 - MainThread _auth.py:211 - authenticate() - DEBUG - account=hiding, user=hiding, database=MDOSDKDEVPH, schema=PUBLIC, warehouse=ETLWAREHOUSE, role=None, request_id=ab2121c1-4703-4e4b-8d83-a33547a41a19
2024-06-24 09:38:28,870 - MainThread _auth.py:244 - authenticate() - DEBUG - body['data']: {'CLIENT_APP_ID': 'PythonSnowpark', 'CLIENT_APP_VERSION': '1.18.0', 'SVN_REVISION': None, 'ACCOUNT_NAME': 'hiding', 'LOGIN_NAME': 'hiding', 'CLIENT_ENVIRONMENT': {'APPLICATION': 'PythonSnowpark', 'OS': 'Windows', 'OS_VERSION': 'Windows-10-10.0.19045-SP0', 'PYTHON_VERSION': '3.11.8', 'PYTHON_RUNTIME': 'CPython', 'PYTHON_COMPILER': 'MSC v.1937 64 bit (AMD64)', 'OCSP_MODE': 'FAIL_OPEN', 'TRACING': 10, 'LOGIN_TIMEOUT': None, 'NETWORK_TIMEOUT': None, 'SOCKET_TIMEOUT': None}, 'AUTHENTICATOR': 'ID_TOKEN', 'TOKEN': 'ver:1-hint:hiding', 'SESSION_PARAMETERS': {'CLIENT_PREFETCH_THREADS': 4, 'CLIENT_STORE_TEMPORARY_CREDENTIAL': True}}
2024-06-24 09:38:28,870 - MainThread retry.py:351 - from_int() - DEBUG - Converted retries value: 1 -> Retry(total=1, connect=None, read=None, redirect=None, status=None)
2024-06-24 09:38:28,871 - MainThread retry.py:351 - from_int() - DEBUG - Converted retries value: 1 -> Retry(total=1, connect=None, read=None, redirect=None, status=None)
2024-06-24 09:38:28,871 - MainThread network.py:1224 - _use_requests_session() - DEBUG - Session status for SessionPool 'hiding.us-east-1.snowflakecomputing.com', SessionPool 1/1 active sessions
2024-06-24 09:38:28,871 - MainThread network.py:875 - _request_exec_wrapper() - DEBUG - remaining request timeout: N/A ms, retry cnt: 1
2024-06-24 09:38:28,871 - MainThread network.py:857 - add_request_guid() - DEBUG - Request guid: a03df552-0d8e-4e65-a944-357737b6eb98
2024-06-24 09:38:28,871 - MainThread network.py:1065 - _request_exec() - DEBUG - socket timeout: 60
2024-06-24 09:38:28,873 - MainThread connectionpool.py:1019 - _new_conn() - DEBUG - Starting new HTTPS connection (1): hiding.us-east-1.snowflakecomputing.com:443
2024-06-24 09:38:29,403 - MainThread ssl_wrap_socket.py:79 - ssl_wrap_socket_with_ocsp() - DEBUG - OCSP Mode: FAIL_OPEN, OCSP response cache file name: None
2024-06-24 09:38:29,403 - MainThread ocsp_snowflake.py:534 - reset_ocsp_response_cache_uri() - DEBUG - ocsp_response_cache_uri: file://C:/Users/patri/AppData/Local/Snowflake/Caches/ocsp_response_cache.json
2024-06-24 09:38:29,403 - MainThread ocsp_snowflake.py:537 - reset_ocsp_response_cache_uri() - DEBUG - OCSP_VALIDATION_CACHE size: 298
2024-06-24 09:38:29,403 - MainThread ocsp_snowflake.py:333 - reset_ocsp_dynamic_cache_server_url() - DEBUG - OCSP response cache server is enabled: http://ocsp.snowflakecomputing.com/ocsp_response_cache.json
2024-06-24 09:38:29,403 - MainThread ocsp_snowflake.py:346 - reset_ocsp_dynamic_cache_server_url() - DEBUG - OCSP dynamic cache server RETRY URL: None
2024-06-24 09:38:29,403 - MainThread ocsp_snowflake.py:970 - validate() - DEBUG - validating certificate: hiding.us-east-1.snowflakecomputing.com
2024-06-24 09:38:29,403 - MainThread ocsp_asn1crypto.py:385 - extract_certificate_chain() - DEBUG - # of certificates: 4
2024-06-24 09:38:29,404 - MainThread ocsp_asn1crypto.py:390 - extract_certificate_chain() - DEBUG - subject: OrderedDict([('common_name', '*.va3.us-east-1.snowflakecomputing.com')]), issuer: OrderedDict([('country_name', 'US'), ('organization_name', 'Amazon'), ('common_name', 'Amazon RSA 2048 M02')])
2024-06-24 09:38:29,404 - MainThread ocsp_asn1crypto.py:390 - extract_certificate_chain() - DEBUG - subject: OrderedDict([('country_name', 'US'), ('organization_name', 'Amazon'), ('common_name', 'Amazon RSA 2048 M02')]), issuer: OrderedDict([('country_name', 'US'), ('organization_name', 'Amazon'), ('common_name', 'Amazon Root CA 1')])
2024-06-24 09:38:29,405 - MainThread ocsp_asn1crypto.py:390 - extract_certificate_chain() - DEBUG - subject: OrderedDict([('country_name', 'US'), ('organization_name', 'Amazon'), ('common_name', 'Amazon Root CA 1')]), issuer: OrderedDict([('country_name', 'US'), ('state_or_province_name', 'Arizona'), ('locality_name', 'Scottsdale'), ('organization_name', 'Starfield Technologies, Inc.'), ('common_name', 'Starfield Services Root Certificate Authority - G2')])
2024-06-24 09:38:29,405 - MainThread ocsp_asn1crypto.py:390 - extract_certificate_chain() - DEBUG - subject: OrderedDict([('country_name', 'US'), ('state_or_province_name', 'Arizona'), ('locality_name', 'Scottsdale'), ('organization_name', 'Starfield Technologies, Inc.'), ('common_name', 'Starfield Services Root Certificate Authority - G2')]), issuer: OrderedDict([('country_name', 'US'), ('organization_name', 'Starfield Technologies, Inc.'), ('organizational_unit_name', 'Starfield Class 2 Certification Authority')])
2024-06-24 09:38:29,407 - MainThread ocsp_asn1crypto.py:413 - create_pair_issuer_subject() - DEBUG - not found issuer_der: OrderedDict([('country_name', 'US'), ('organization_name', 'Starfield Technologies, Inc.'), ('organizational_unit_name', 'Starfield Class 2 Certification Authority')])
2024-06-24 09:38:29,407 - MainThread ocsp_snowflake.py:734 - find_cache() - DEBUG - hit cache for subject: OrderedDict([('common_name', '*.va3.us-east-1.snowflakecomputing.com')])
2024-06-24 09:38:29,409 - MainThread ocsp_asn1crypto.py:205 - is_valid_time() - DEBUG - Verifying the attached certificate is signed by the issuer. Valid Not After: 2025-12-10 00:00:00+00:00
2024-06-24 09:38:29,409 - MainThread ocsp_snowflake.py:734 - find_cache() - DEBUG - hit cache for subject: OrderedDict([('country_name', 'US'), ('organization_name', 'Amazon'), ('common_name', 'Amazon RSA 2048 M02')])
2024-06-24 09:38:29,410 - MainThread ocsp_asn1crypto.py:205 - is_valid_time() - DEBUG - Verifying the attached certificate is signed by the issuer. Valid Not After: 2025-12-10 00:00:00+00:00
2024-06-24 09:38:29,411 - MainThread ocsp_snowflake.py:734 - find_cache() - DEBUG - hit cache for subject: OrderedDict([('country_name', 'US'), ('organization_name', 'Amazon'), ('common_name', 'Amazon Root CA 1')])
2024-06-24 09:38:29,412 - MainThread ocsp_asn1crypto.py:205 - is_valid_time() - DEBUG - Verifying the attached certificate is signed by the issuer. Valid Not After: 2025-05-07 12:00:00+00:00
2024-06-24 09:38:29,412 - MainThread ocsp_snowflake.py:734 - find_cache() - DEBUG - hit cache for subject: OrderedDict([('country_name', 'US'), ('state_or_province_name', 'Arizona'), ('locality_name', 'Scottsdale'), ('organization_name', 'Starfield Technologies, Inc.'), ('common_name', 'Starfield Services Root Certificate Authority - G2')])
2024-06-24 09:38:29,414 - MainThread ocsp_snowflake.py:1027 - _validate() - DEBUG - ok
2024-06-24 09:38:29,547 - MainThread connectionpool.py:474 - _make_request() - DEBUG - https://hiding.us-east-1.snowflakecomputing.com:443 "POST /session/v1/login-request?request_id=ab2121c1-4703-4e4b-8d83-a33547a41a19&databaseName=hiding&schemaName=PUBLIC&warehouse=ETLWAREHOUSE&request_guid=hiding HTTP/1.1" 200 1707
2024-06-24 09:38:29,547 - MainThread network.py:1092 - _request_exec() - DEBUG - SUCCESS
2024-06-24 09:38:29,547 - MainThread network.py:1229 - _use_requests_session() - DEBUG - Session status for SessionPool 'hiding.us-east-1.snowflakecomputing.com', SessionPool 0/1 active sessions
2024-06-24 09:38:29,547 - MainThread network.py:745 - _post_request() - DEBUG - ret[code] = None, after post request
2024-06-24 09:38:29,547 - MainThread _auth.py:371 - authenticate() - DEBUG - completed authentication
2024-06-24 09:38:29,547 - MainThread _auth.py:418 - authenticate() - DEBUG - token = ******
2024-06-24 09:38:29,547 - MainThread _auth.py:426 - authenticate() - DEBUG - master_token = ******
2024-06-24 09:38:29,547 - MainThread _auth.py:434 - authenticate() - DEBUG - id_token = NULL
2024-06-24 09:38:29,547 - MainThread _auth.py:442 - authenticate() - DEBUG - mfa_token = NULL
2024-06-24 09:38:29,547 - MainThread connection.py:845 - cursor() - DEBUG - cursor
@github-actions github-actions bot changed the title using connections.toml always returns a "Bad owner or permissions" on UserWarning SNOW-1502056: using connections.toml always returns a "Bad owner or permissions" on UserWarning Jun 24, 2024
@sfc-gh-dszmolka sfc-gh-dszmolka self-assigned this Jun 25, 2024
@sfc-gh-dszmolka sfc-gh-dszmolka added status-triage Issue is under initial triage and removed needs triage labels Jun 25, 2024
@sfc-gh-dszmolka
Copy link
Contributor

sfc-gh-dszmolka commented Jun 25, 2024

hello - thanks for raising this. so we do check for file permissions mode and if the file is readable by Group or Others
https://github.com/snowflakedb/snowflake-connector-python/blob/v3.11.0/src/snowflake/connector/config_manager.py#L336

but i'm not sure if the issue comes from the PythonConnector or not. reproduced the issue by creating the connections.toml, setting it as read-only mode :

PS C:\temp\python1978> Get-Acl .\connections.toml |Format-List


Path   : Microsoft.PowerShell.Core\FileSystem::C:\temp\python1978\connections.toml
Owner  : MYHOST\dszmolka
Group  : MYHOST\None
Access : MYHOST\dszmolka Allow  Read, Synchronize
Audit  :
Sddl   : O:S-1-5-21-1293141090-215775074-2841561624-1000G:S-1-5-21-1293141090-215775074-2841561624513D:PAI(A;;FR;;;S-1-5-21-1293141090-215775074-2841561624-1000)

(from what i understand about Windows; this looks like as of only me the owner have Read and Synchronize (whatever that is) permissions, nobody has anything else)

but when adding some debug logging to config_manager.py to actually write out the file permissions it is seeing on the file:

> python .\test.py
C:\temp\python1978

filep.stat().st_mode: 33206, oct: 0o100666. stat.S_IRGRP: 32, oct: 0o40. stat.S_IROTH: 4, oct: 0o4
C:\temp\python1978\venv\lib\site-packages\snowflake\connector\config_manager.py:352: UserWarning: Bad owner or permissions on C:\temp\python1978\connections.toml
  warn(f"Bad owner or permissions on {str(filep)}{chmod_message}")

which if i got correctly, the least-significant 4 bits (0666) show the file permissions similarly to Unix; which is quite disturbing because 0666 means the file is readable+writable for Owner, Group, and Others too. So the error message (complaining about bad permissions) makes sense at the first glance; as it should be only readable to Owner, if this is really the permission bits.

I'll keep digging how it would be the best to actually enforce the necessary 0600 permission on Windows (it's a simple instant chmod on Unix)

@sfc-gh-dszmolka
Copy link
Contributor

well determining the file permissions on Windows with the same method as on Unix, don't seem to work. We'll need to see how we want to address this.

@sfc-gh-dszmolka sfc-gh-dszmolka added status-triage_done Initial triage done, will be further handled by the driver team and removed status-triage Issue is under initial triage labels Jun 25, 2024
@patrickhowerter
Copy link
Author

A couple of options I see here as this appears to be difficult to implement across operating systems.

  1. Allow an argument to Session.builder.config method, such as "check_config_file_permissions", with the default being False. In our use case, we do not have any private information (authenticator = "externalbrowser") in our config file anyways..
  2. Give the end users a function that writes the configuration file (this would automatically write the file with the appropriate permissions. This avoids end users going down the rabbit hole of trying to figure out how to permission the file correctly..

@citenx
Copy link

citenx commented Aug 9, 2024

A couple of options I see here as this appears to be difficult to implement across operating systems.

  1. Allow an argument to Session.builder.config method, such as "check_config_file_permissions", with the default being False. In our use case, we do not have any private information (authenticator = "externalbrowser") in our config file anyways..
  2. Give the end users a function that writes the configuration file (this would automatically write the file with the appropriate permissions. This avoids end users going down the rabbit hole of trying to figure out how to permission the file correctly..

I'm suppressing these warnings with the following as it makes my console output unreadable:

import warnings
warnings.filterwarnings(
    action='ignore',
    category=UserWarning,
    module='snowflake.connector'
)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug status-triage_done Initial triage done, will be further handled by the driver team
Projects
None yet
Development

No branches or pull requests

4 participants