)]}'
{"id":"openstack%2Fpython-swiftclient~303863","triplet_id":"openstack%2Fpython-swiftclient~master~I12e151adcb6084d801c6dfed21d82232a3259aea","project":"openstack/python-swiftclient","branch":"master","topic":"bug/1565112","hashtags":[],"change_id":"I12e151adcb6084d801c6dfed21d82232a3259aea","subject":"Support client certificate/key","status":"MERGED","created":"2016-04-10 21:24:50.000000000","updated":"2016-05-19 22:20:18.000000000","submitted":"2016-05-19 22:20:17.000000000","submitter":{"_account_id":3,"name":"Jenkins","username":"jenkins"},"total_comment_count":0,"unresolved_comment_count":0,"has_review_started":true,"meta_rev_id":"a0f0e8d0d9d317ae038fe647a8230f68050ee19a","_number":303863,"virtual_id_number":303863,"owner":{"_account_id":8124,"name":"cbrandily","email":"zzelle@gmail.com","username":"cbrandily"},"actions":{},"labels":{"Verified":{"approved":{"_account_id":3,"name":"Jenkins","username":"jenkins"},"all":[{"value":2,"date":"2016-05-19 22:20:17.000000000","_account_id":3,"name":"Jenkins","username":"jenkins"},{"value":0,"_account_id":597,"name":"Pete Zaitcev","email":"zaitcev@kotori.zaitcev.us","username":"zaitcev"},{"value":0,"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"}],"values":{"-2":"Fails","-1":"Doesn\u0027t seem to work"," 0":"No score","+1":"Works for me","+2":"Verified"},"description":"","default_value":0,"optional":true},"Code-Review":{"approved":{"_account_id":597,"name":"Pete Zaitcev","email":"zaitcev@kotori.zaitcev.us","username":"zaitcev"},"all":[{"value":0,"_account_id":3,"name":"Jenkins","username":"jenkins"},{"value":2,"date":"2016-05-19 20:19:21.000000000","_account_id":597,"name":"Pete Zaitcev","email":"zaitcev@kotori.zaitcev.us","username":"zaitcev"},{"value":2,"date":"2016-04-19 22:38:05.000000000","permitted_voting_range":{"min":2,"max":2},"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"}],"values":{"-2":"Do not merge","-1":"This patch needs further work before it can be merged"," 0":"No score","+1":"Looks good to me, but someone else must approve","+2":"Looks good to me (core reviewer)"},"description":"","default_value":0,"optional":true},"Workflow":{"approved":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"all":[{"value":0,"_account_id":3,"name":"Jenkins","username":"jenkins"},{"value":0,"_account_id":597,"name":"Pete Zaitcev","email":"zaitcev@kotori.zaitcev.us","username":"zaitcev"},{"value":1,"date":"2016-05-19 20:28:06.000000000","permitted_voting_range":{"min":1,"max":1},"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"}],"values":{"-1":"Work in progress"," 0":"Ready for reviews","+1":"Approved"},"description":"","default_value":0,"optional":true}},"removable_reviewers":[],"reviewers":{"REVIEWER":[{"_account_id":3,"name":"Jenkins","username":"jenkins"},{"_account_id":597,"name":"Pete Zaitcev","email":"zaitcev@kotori.zaitcev.us","username":"zaitcev"},{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"}]},"pending_reviewers":{},"reviewer_updates":[{"updated":"2016-05-19 20:19:21.000000000","updated_by":{"_account_id":597,"name":"Pete Zaitcev","email":"zaitcev@kotori.zaitcev.us","username":"zaitcev"},"reviewer":{"_account_id":597,"name":"Pete Zaitcev","email":"zaitcev@kotori.zaitcev.us","username":"zaitcev"},"state":"REVIEWER"},{"updated":"2016-05-19 20:28:06.000000000","updated_by":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"reviewer":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"state":"REVIEWER"},{"updated":"2016-05-19 22:20:17.000000000","updated_by":{"_account_id":3,"name":"Jenkins","username":"jenkins"},"reviewer":{"_account_id":3,"name":"Jenkins","username":"jenkins"},"state":"REVIEWER"}],"messages":[{"id":"b2f3db71ccbbcd27f94523cfe6993bb864ecd21f","author":{"_account_id":8124,"name":"cbrandily","email":"zzelle@gmail.com","username":"cbrandily"},"date":"2016-04-10 21:24:50.000000000","message":"Uploaded patch set 1.","accounts_in_message":[],"_revision_number":1},{"id":"8983f4177ff83defa954da0e3ed596f96a9d746c","author":{"_account_id":3,"name":"Jenkins","username":"jenkins"},"date":"2016-04-10 22:23:32.000000000","message":"Patch Set 1: Verified+1\n\nBuild succeeded (check pipeline).\n\n- gate-python-swiftclient-docs http://docs-draft.openstack.org/63/303863/1/check/gate-python-swiftclient-docs/76592ec//doc/build/html/ : SUCCESS in 1m 25s\n- gate-python-swiftclient-pep8 http://logs.openstack.org/63/303863/1/check/gate-python-swiftclient-pep8/4f25ba4/ : SUCCESS in 2m 15s\n- gate-python-swiftclient-python27 http://logs.openstack.org/63/303863/1/check/gate-python-swiftclient-python27/ba38419/ : SUCCESS in 2m 17s\n- gate-python-swiftclient-python34 http://logs.openstack.org/63/303863/1/check/gate-python-swiftclient-python34/d3ab70d/ : SUCCESS in 3m 01s\n- gate-python-swiftclient-pypy http://logs.openstack.org/63/303863/1/check/gate-python-swiftclient-pypy/effd485/ : SUCCESS in 2m 41s (non-voting)\n- gate-tempest-dsvm-neutron-src-python-swiftclient http://logs.openstack.org/63/303863/1/check/gate-tempest-dsvm-neutron-src-python-swiftclient/9caba20/ : SUCCESS in 58m 35s\n- gate-swift-dsvm-functional http://logs.openstack.org/63/303863/1/check/gate-swift-dsvm-functional/241620b/ : SUCCESS in 19m 32s\n- gate-swiftclient-dsvm-functional http://logs.openstack.org/63/303863/1/check/gate-swiftclient-dsvm-functional/1ac3eed/ : SUCCESS in 10m 43s","accounts_in_message":[],"_revision_number":1},{"id":"2e43651eb732a2097551fff543b3daeea40e539c","author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"date":"2016-04-15 20:38:43.000000000","message":"Patch Set 1: Code-Review+1\n\nThe plumbing all seems reasonable, and the tests verify it well.\n\nHow would this be used in practice? I found (but haven\u0027t finished reading) [1] and [2]; it sounds like we wouldn\u0027t need any usernames, passwords, or project/tenant identifiers. Is that accurate? If so, we\u0027ll need to rethink what\u0027s required in shell.py:parse_args.\n\nIs the idea to use the cert/key to talk to keystone and obtain a token \u0026 endpoint to use to talk to swift, or (provided we know the endpoint already) start talking to swift straight away using the cert/key *in place of* a token? Either way, this sounds cool!\n\nIf it\u0027s the latter, though, we should include an early exit around [3], basically treating cert like an auth token. (Or cert+key? I\u0027m not clear yet on when the key may be required.)\n\n[1] http://docs.openstack.org/developer/keystone/configure_tokenless_x509.html\n\n[2] http://specs.openstack.org/openstack/keystone-specs/specs/liberty/keystone-tokenless-authz-with-x509-ssl-client-cert.html#rest-api-impact\n\n[3] https://github.com/openstack/python-swiftclient/blob/ab636c1/swiftclient/shell.py#L1239-L1242","accounts_in_message":[],"_revision_number":1},{"id":"590fcfc19f6e8079ea7a6e0a4ddb890d09925994","author":{"_account_id":8124,"name":"cbrandily","email":"zzelle@gmail.com","username":"cbrandily"},"date":"2016-04-15 22:33:08.000000000","message":"Patch Set 1:\n\n\u003e How would this be used in practice? I found (but haven\u0027t finished\n \u003e reading) [1] and [2]; it sounds like we wouldn\u0027t need any\n \u003e usernames, passwords, or project/tenant identifiers. Is that\n \u003e accurate? If so, we\u0027ll need to rethink what\u0027s required in\n \u003e shell.py:parse_args.\n\nI don\u0027t use client certificates as a replacement to user/password BUT as an extension to implement 2-factor authentication[1][2]:\n\n* the password is the \"something i know\"[2]\n* the certificate is the \"something i own\"[2]\n\nAuthentication using client certificate only doesn\u0027t seem to be supported by clients or at least not supported by  OpenStackClient, novaclient, cinderclient, heatclient. So should i add its support in swiftclient? \n\n\n \u003e If it\u0027s the latter, though, we should include an early exit around\n \u003e [3], basically treating cert like an auth token. (Or cert+key? I\u0027m\n \u003e not clear yet on when the key may be required.)\n\nThe key (private part) is required to prove you \"own\" the certificate (public part) which contains typically identity information. You can provide them separately:\n\n swift --os-cert myname.crt --os-key myname.key ...\n\nor merge them:\n\n cat myname.crt myname.key \u003e myname.crtkey\n swift --os-cert myname.crtkey ...\n\nbecause requests supports both way\n\n\n[1] https://en.wikipedia.org/wiki/Two-factor_authentication#Components\n[2] http://blog.gemalto.com/blog/2011/09/05/three-factor-authentication-something-you-know-something-you-have-something-you-are/","accounts_in_message":[],"_revision_number":1},{"id":"0b4fe445f83ddf78e99d64740c7f1c21ce33c24f","author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"date":"2016-04-15 22:59:16.000000000","message":"Patch Set 1:\n\nOK, cool. So parse_args is fine as it is, and the expectation is that all the normal auth options are *also* present. I\u0027m in no rush to add support for pure client-cert authentication if no other projects are using it.\n\nIs there an expectation that Swift servers (when properly configured) should recognize client certs, and reject connections with missing/unrecognized certs? I.e., is the plumbing down into client.HTTPConnection necessary for all cases, or is it mainly for v1 auth? Should we be adding plumbing for functions like client.get_object [1]?\n\nDo you have any pointers on how to get a client-cert-aware setup up and running, so I can really play around with it?\n\n[1] https://github.com/openstack/python-swiftclient/blob/9b8ab67/swiftclient/client.py#L1059","accounts_in_message":[],"_revision_number":1},{"id":"04498af96216d319a6e66a59ed44658432b225cf","author":{"_account_id":8124,"name":"cbrandily","email":"zzelle@gmail.com","username":"cbrandily"},"date":"2016-04-15 23:39:45.000000000","message":"Patch Set 1:\n\n\u003e OK, cool. So parse_args is fine as it is, and the expectation is\n \u003e that all the normal auth options are *also* present. I\u0027m in no rush\n \u003e to add support for pure client-cert authentication if no other\n \u003e projects are using it.\n \u003e \n \u003e Is there an expectation that Swift servers (when properly\n \u003e configured) should recognize client certs, and reject connections\n \u003e with missing/unrecognized certs? I.e., is the plumbing down into\n \u003e client.HTTPConnection necessary for all cases, or is it mainly for\n \u003e v1 auth? Should we be adding plumbing for functions like\n \u003e client.get_object [1]?\n/me looking\n\n \u003e Do you have any pointers on how to get a client-cert-aware setup up\n \u003e and running, so I can really play around with it?\n\nA typical setup is to hide swift being a SSL proxy performing client cert check. It implies to configure a SSL proxy like nginx:\n\n # cat /etc/nginx/sites-enabled/secure \n server {\n  listen              443 ssl;\n  server_name         blah;\n  ssl_certificate     /etc/nginx/server.crt;\n  ssl_certificate_key /etc/nginx/server.key;\n\n  # NOTE(zzelle): the client certificate part\n  # CA to check client certs\n  ssl_client_certificate ca.client.crt;\n  # Client cert check must succeed\n  ssl_verify_client on;\n\n  location / {\n    proxy_pass http://\u003cswift\u003e;\n\n    # NOTE(zzelle): rewrite location headers + bodies\n    proxy_set_header Host TOREWRITE;\n    proxy_redirect http://TOREWRITE https://$http_host;\n    sub_filter     http://TOREWRITE https://$http_host;\n    sub_filter_once off;\n    sub_filter_types *;\n  }\n}\n\nAND the annoying part to build a Certificate Authority (CA) ca.client.crt and client certificates and their private keys\n* you can use[1][2] to help you to build them\n* or use existing samples[3]\n** ca.crt \u003d\u003e ca.client.crt in nginx conf\n** client.crt \u003d\u003e --os-cert client.crt\n** client.key \u003d\u003e --os-key client.key\n\nI didn\u0027t tested [1][2] and tested [3] a long time ago.\n\n\n[1] https://gist.github.com/mtigas/952344\n[2] http://nategood.com/client-side-certificate-authentication-in-ngi\n[3] https://github.com/OpenVPN/openvpn/tree/master/sample/sample-keys","accounts_in_message":[],"_revision_number":1},{"id":"1fe051a8e40505bc9eb38b821b48fd5e0c2b741a","author":{"_account_id":8124,"name":"cbrandily","email":"zzelle@gmail.com","username":"cbrandily"},"date":"2016-04-16 09:47:45.000000000","message":"Patch Set 1:\n\n\u003e v1 auth? Should we be adding plumbing for functions like\n \u003e client.get_object [1]?\n\nI am not sure how we can recheck [1] as get_object is always called in swiftclient using _retry[2] method which calls get_object with http_conn[3]\n\n\n[1] https://github.com/openstack/python-swiftclient/blob/9b8ab67/swiftclient/client.py#L1059\n[2] https://github.com/openstack/python-swiftclient/blob/9b8ab67/swiftclient/client.py#L1492\n[3] https://github.com/openstack/python-swiftclient/blob/9b8ab67/swiftclient/client.py#L1507-L1509","accounts_in_message":[],"_revision_number":1},{"id":"b6e336646c71a9f286a81822b07f6b479be63e06","author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"date":"2016-04-19 22:38:05.000000000","message":"Patch Set 1: Code-Review+2\n\nOK, I got nginx reverse-proxying to my all-in-one, generated a bunch of certs, made them available to both server and client, and saw that passing --os-cert and --os-key worked, while all of these failed:\n\n* skip the cert\n* skip the key\n* use a self-signed cert/key\n\nSome of the error messages aren\u0027t great, but I blame requests/ssl. For example, if you omit/forget the key, you get:\n\n  [SSL] PEM lib (_ssl.c:2599)\n\nAs far as the non-Connection client.py functions, something like http://paste.openstack.org/show/494717/ *would* allow developers to do something like\n\n import swiftclient\n headers, containers \u003d swiftclient.get_account(\n     \u0027https://saio/v1/AUTH_test2\u0027,\n     \u0027AUTH_tk5f060098090a4eb3a61e2b65245b74ce\u0027,\n     cacert\u003d\u0027root.pem\u0027, cert\u003d\u0027client.crt\u0027, cert_key\u003d\u0027client.key\u0027)\n\nHowever,\n\n* we don\u0027t currently plumb in cacert (so users are probably used to SSL sucking through this API),\n* it adds a lot of new and rarely-used args to a lot of functions, and\n* it could always be done later, when someone actually asks for it.\n\nSo I don\u0027t think that should hold this up. Good work!","accounts_in_message":[],"_revision_number":1},{"id":"12f3d964c11439ffc62f287759a83dd76566d15d","author":{"_account_id":597,"name":"Pete Zaitcev","email":"zaitcev@kotori.zaitcev.us","username":"zaitcev"},"date":"2016-05-19 20:19:21.000000000","message":"Patch Set 1: Code-Review+2","accounts_in_message":[],"_revision_number":1},{"id":"596c86dd1755773fcea66ec2b4fd3832cfa27104","author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"date":"2016-05-19 20:28:06.000000000","message":"Patch Set 1: Workflow+1","accounts_in_message":[],"_revision_number":1},{"id":"b08b8218ab58283a5652c1624e2f885dcd07649a","author":{"_account_id":3,"name":"Jenkins","username":"jenkins"},"date":"2016-05-19 20:28:19.000000000","message":"Patch Set 1: -Verified\n\nStarting gate jobs.\nhttp://status.openstack.org/zuul/","accounts_in_message":[],"_revision_number":1},{"id":"2c92290d5a314225ee443cc003670d961e5d9b59","author":{"_account_id":3,"name":"Jenkins","username":"jenkins"},"date":"2016-05-19 22:20:17.000000000","message":"Patch Set 1: Verified+2\n\nBuild succeeded (gate pipeline).\n\n- gate-python-swiftclient-docs http://docs-draft.openstack.org/63/303863/1/gate/gate-python-swiftclient-docs/944e3e2//doc/build/html/ : SUCCESS in 2m 38s\n- gate-python-swiftclient-pep8 http://logs.openstack.org/63/303863/1/gate/gate-python-swiftclient-pep8/aff953e/ : SUCCESS in 3m 35s\n- gate-python-swiftclient-python27 http://logs.openstack.org/63/303863/1/gate/gate-python-swiftclient-python27/73ccad6/ : SUCCESS in 2m 26s\n- gate-python-swiftclient-python34 http://logs.openstack.org/63/303863/1/gate/gate-python-swiftclient-python34/393f42d/ : SUCCESS in 2m 02s\n- gate-tempest-dsvm-neutron-src-python-swiftclient http://logs.openstack.org/63/303863/1/gate/gate-tempest-dsvm-neutron-src-python-swiftclient/3f7d2f5/ : SUCCESS in 1h 11m 48s\n- gate-swift-dsvm-functional http://logs.openstack.org/63/303863/1/gate/gate-swift-dsvm-functional/5ee9de4/ : SUCCESS in 25m 15s\n- gate-swiftclient-dsvm-functional http://logs.openstack.org/63/303863/1/gate/gate-swiftclient-dsvm-functional/8736aab/ : SUCCESS in 19m 44s","accounts_in_message":[],"_revision_number":1},{"id":"2ad6fa1c4e4cd669e72cdbbb9a749dd4327caebc","date":"2016-05-19 22:20:18.000000000","message":"Change has been successfully merged into the git repository by Jenkins","accounts_in_message":[],"_revision_number":1}],"current_revision_number":1,"current_revision":"450f505c35f8762cca29d56b6e928490288ec166","revisions":{"450f505c35f8762cca29d56b6e928490288ec166":{"kind":"REWORK","_number":1,"created":"2016-04-10 21:24:50.000000000","uploader":{"_account_id":8124,"name":"cbrandily","email":"zzelle@gmail.com","username":"cbrandily"},"ref":"refs/changes/63/303863/1","fetch":{"anonymous http":{"url":"https://review.opendev.org/openstack/python-swiftclient","ref":"refs/changes/63/303863/1","commands":{"Checkout":"git fetch https://review.opendev.org/openstack/python-swiftclient refs/changes/63/303863/1 \u0026\u0026 git checkout FETCH_HEAD","Cherry Pick":"git fetch https://review.opendev.org/openstack/python-swiftclient refs/changes/63/303863/1 \u0026\u0026 git cherry-pick FETCH_HEAD","Format Patch":"git fetch https://review.opendev.org/openstack/python-swiftclient refs/changes/63/303863/1 \u0026\u0026 git format-patch -1 --stdout FETCH_HEAD","Pull":"git pull https://review.opendev.org/openstack/python-swiftclient refs/changes/63/303863/1"}}},"commit":{"parents":[{"commit":"015903e383a27318918ee7827574ecb120110ae2","subject":"Merge \"Port from optparse to argparse\"","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/python-swiftclient/commit/015903e383a27318918ee7827574ecb120110ae2"}]}],"author":{"name":"Cedric Brandily","email":"zzelle@gmail.com","date":"2016-04-10 21:18:17.000000000","tz":120},"committer":{"name":"Cedric Brandily","email":"zzelle@gmail.com","date":"2016-04-10 21:20:49.000000000","tz":120},"subject":"Support client certificate/key","message":"Support client certificate/key\n\nThis change enables to specify a client certificate/key with:\n * usual CLI options (--os-cert/--os-key)\n * usual environment variables ($OS_CERT/$OS_KEY)\n\nCloses-Bug: #1565112\nChange-Id: I12e151adcb6084d801c6dfed21d82232a3259aea\n","web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/python-swiftclient/commit/450f505c35f8762cca29d56b6e928490288ec166"}],"resolve_conflicts_web_links":[{"name":"gitea","tooltip":"Open in GitWeb","url":"https://opendev.org/openstack/python-swiftclient/commit/450f505c35f8762cca29d56b6e928490288ec166"}]},"branch":"refs/heads/master"}},"requirements":[],"submit_records":[],"submit_requirements":[]}
