From 0b5de2aa7a747856aa03d93fb62cd26b68ddff19 Mon Sep 17 00:00:00 2001 From: danielgrippi Date: Fri, 24 Jun 2011 11:20:25 -0700 Subject: [PATCH] WIP getting rid of app_url in params --- Gemfile | 4 +- Gemfile.lock | 17 +++--- app/controllers/authorizations_controller.rb | 16 +++-- spec/chubbies/Gemfile | 4 +- spec/chubbies/Gemfile.lock | 5 +- .../authorizations_controller_spec.rb | 58 ++++++++++--------- 6 files changed, 56 insertions(+), 48 deletions(-) diff --git a/Gemfile b/Gemfile index fbc7e0078..e0eee167a 100644 --- a/Gemfile +++ b/Gemfile @@ -96,6 +96,6 @@ group :test do gem 'rspec-instafail', '>= 0.1.7', :require => false gem 'fuubar' - gem 'diaspora-client', :git => 'git@github.com:diaspora/diaspora-client.git' - #:path => "~/work/diaspora-client" + gem 'diaspora-client', :path => "~/workspace/diaspora-client" #:git => 'git@github.com:diaspora/diaspora-client.git' + end diff --git a/Gemfile.lock b/Gemfile.lock index ce4c7fc00..c5dbe5c73 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -38,8 +38,14 @@ GIT eventmachine (>= 0.12.9) GIT - remote: git@github.com:diaspora/diaspora-client.git - revision: 6b1b07fba73106755acd77d6def3e503df007a3f + remote: https://github.com/zhitomirskiyi/ruby-jwt + revision: fa7f46b5ac3653e30cf60abc78de9ffb3319dc0c + specs: + jwt (0.1.3) + json (>= 1.2.4) + +PATH + remote: ~/workspace/diaspora-client specs: diaspora-client (0.0.0) activerecord @@ -48,13 +54,6 @@ GIT oauth2 sinatra -GIT - remote: https://github.com/zhitomirskiyi/ruby-jwt - revision: fa7f46b5ac3653e30cf60abc78de9ffb3319dc0c - specs: - jwt (0.1.3) - json (>= 1.2.4) - GEM remote: http://rubygems.org/ specs: diff --git a/app/controllers/authorizations_controller.rb b/app/controllers/authorizations_controller.rb index 7ca84e012..17f917b23 100644 --- a/app/controllers/authorizations_controller.rb +++ b/app/controllers/authorizations_controller.rb @@ -25,15 +25,18 @@ class AuthorizationsController < ApplicationController def token require 'jwt' - if (!params[:type] == 'client_associate' || !params[:manifest_url]) + signed_string = Base64.decode64(params[:signed_string]) + app_url = signed_string.split(';')[0] + + if (!params[:type] == 'client_associate' && !app_url) render :text => "bad request: #{params.inspect}", :status => 403 return end - packaged_manifest = JSON.parse(RestClient.get(params[:manifest_url]).body) + packaged_manifest = JSON.parse(RestClient.get("#{app_url}/manifest.json").body) public_key = OpenSSL::PKey::RSA.new(packaged_manifest['public_key']) manifest = JWT.decode(packaged_manifest['jwt'], public_key) - message = verify(params[:signed_string], params[:signature], public_key) + message = verify(signed_string, Base64.decode64(params[:signature]), public_key, manifest) if not (message =='ok') render :text => message, :status => 403 elsif manifest["homepage_url"].match(/^http:\/\/(localhost:\d+|chubbi\.es|cubbi\.es)\/$/).nil? @@ -69,17 +72,18 @@ class AuthorizationsController < ApplicationController # @param [String] sig A Base64 encoded signature of the decoded signed_string with public_key. # @param [OpenSSL::PKey::RSA] public_key The application's public key to verify sig with. # @return [String] 'ok' or an error message. - def verify( enc_signed_string, sig, public_key) - signed_string = Base64.decode64(enc_signed_string) + def verify( signed_string, sig, public_key, manifest) split = signed_string.split(';') + app_url = split[0] time = split[2] nonce = split[3] return 'blank public key' if public_key.n.nil? + return 'the app url in the manifest does not match the url passed in the parameters' if manifest["homepage_url"] != app_url return 'key too small, use at least 2048 bits' if public_key.n.num_bits < 2048 return "invalid time" unless valid_time?(time) return 'invalid nonce' unless valid_nonce?(nonce) - return 'invalid signature' unless verify_signature(signed_string, Base64.decode64(sig), public_key) + return 'invalid signature' unless verify_signature(signed_string, sig, public_key) 'ok' end diff --git a/spec/chubbies/Gemfile b/spec/chubbies/Gemfile index 4265b8447..45cf891a1 100644 --- a/spec/chubbies/Gemfile +++ b/spec/chubbies/Gemfile @@ -7,6 +7,6 @@ gem 'json' gem 'shotgun' gem 'sqlite3' gem 'activerecord', '3.0.3' -gem 'diaspora-client', :git => 'git@github.com:diaspora/diaspora-client.git' - #:path => "~/work/diaspora-client" +gem 'diaspora-client', :path => "~/workspace/diaspora-client" #:git => 'git@github.com:diaspora/diaspora-client.git' + diff --git a/spec/chubbies/Gemfile.lock b/spec/chubbies/Gemfile.lock index fab831ebc..b9370ee7c 100644 --- a/spec/chubbies/Gemfile.lock +++ b/spec/chubbies/Gemfile.lock @@ -1,6 +1,5 @@ -GIT - remote: git@github.com:diaspora/diaspora-client.git - revision: 6b1b07fba73106755acd77d6def3e503df007a3f +PATH + remote: ~/workspace/diaspora-client specs: diaspora-client (0.0.0) activerecord diff --git a/spec/controllers/authorizations_controller_spec.rb b/spec/controllers/authorizations_controller_spec.rb index 8a45aa30f..01784f339 100644 --- a/spec/controllers/authorizations_controller_spec.rb +++ b/spec/controllers/authorizations_controller_spec.rb @@ -19,25 +19,26 @@ describe AuthorizationsController do @time = Time.now Time.stub(:now).and_return(@time) @nonce = 'asdfsfasf' - @signable_string = ["http://chubbi.es/",'http://pod.pod/',"#{Time.now.to_i}", @nonce].join(';') + @signed_string = ["http://chubbi.es",'http://pod.pod',"#{Time.now.to_i}", @nonce].join(';') + @signature = @private_key.sign(OpenSSL::Digest::SHA256.new, @signed_string) + + @manifest = { + "name" => "Chubbies", + "description" => "The best way to chub.", + "homepage_url" => "http://chubbi.es", + "icon_url" => "#", + "permissions_overview" => "I will use the permissions this way!", + } end describe '#token' do before do - manifest = { - "name" => "Chubbies", - "description" => "The best way to chub.", - "homepage_url" => "http://chubbi.es/", - "icon_url" => "#", - "permissions_overview" => "I will use the permissions this way!", - } - - packaged_manifest = {:public_key => @public_key.export, :jwt => JWT.encode(manifest, @private_key, "RS256")}.to_json + packaged_manifest = {:public_key => @public_key.export, :jwt => JWT.encode(@manifest, @private_key, "RS256")}.to_json stub_request(:get, "http://chubbi.es/manifest.json"). to_return(:status => 200, :body => packaged_manifest, :headers => {}) - @params_hash = {:type => 'client_associate', :manifest_url => "http://chubbi.es/manifest.json" } + @params_hash = {:type => 'client_associate', :signed_string => Base64.encode64(@signed_string), :signature => Base64.encode64(@signature)} end context 'special casing (temporary, read note in the controller)' do @@ -107,12 +108,13 @@ describe AuthorizationsController do end it 'verifies the signable string validity(time,nonce,sig)' do - @controller.should_receive(:verify){|a,b,c| - a.should == 'signed_string' - b.should == 'sig' + @controller.should_receive(:verify){|a,b,c,d| + a.should == @signed_string + b.should == @signature c.export.should == @public_key.export + d.should == @manifest } - post :token, @params_hash.merge!({:signed_string => 'signed_string', :signature => 'sig'}) + post :token, @params_hash end end @@ -152,31 +154,35 @@ describe AuthorizationsController do describe '#verify' do before do @controller.stub!(:verify_signature) - @sig = Base64.encode64('sig') + @sig = 'sig' end it 'checks for valid time' do @controller.should_receive(:valid_time?).with(@time.to_i.to_s) - @controller.verify(Base64.encode64(@signable_string), @sig, @public_key) + @controller.verify(@signed_string, @sig, @public_key, @manifest) end it 'checks the signature' do - @controller.should_receive(:verify_signature).with(@signable_string, 'sig', @public_key) - @controller.verify(Base64.encode64(@signable_string), @sig, @public_key) + @controller.should_receive(:verify_signature).with(@signed_string, 'sig', @public_key) + @controller.verify(@signed_string, @sig, @public_key, @manifest) end it 'checks for valid nonce' do @controller.should_receive(:valid_nonce?).with(@nonce) - @controller.verify(Base64.encode64(@signable_string), @sig, @public_key) + @controller.verify(@signed_string, @sig, @public_key, @manifest) end it 'checks for public key' do - @controller.verify(Base64.encode64(@signable_string), @sig, RSA.new()).should == "blank public key" + @controller.verify(@signed_string, @sig, RSA.new(), @manifest).should == "blank public key" + end + + it 'checks consistency of app_url' do + @controller.verify(@signed_string, @sig, @public_key, @manifest.merge({"homepage_url" => "http://badsite.com"})).should == "the app url in the manifest does not match the url passed in the parameters" end it 'checks key size' do short_key = RSA.generate(100) RSA.stub!(:new).and_return(short_key) - @controller.verify(Base64.encode64(@signable_string), @sig, RSA.generate(100).public_key). + @controller.verify(@signed_string, @sig, RSA.generate(100).public_key, @manifest). should == "key too small, use at least 2048 bits" end end @@ -184,17 +190,17 @@ describe AuthorizationsController do describe '#verify_signature' do before do - @sig = @private_key.sign(OpenSSL::Digest::SHA256.new, @signable_string) + @sig = @private_key.sign(OpenSSL::Digest::SHA256.new, @signed_string) end it 'returns true if the signature is valid' do - @controller.verify_signature(@signable_string, @sig, @public_key).should be_true + @controller.verify_signature(@signed_string, @sig, @public_key).should be_true end it 'returns false if the signature is invalid' do - @signable_string = "something else" + @signed_string = "something else" - @controller.verify_signature(@signable_string, @sig, @public_key).should be_false + @controller.verify_signature(@signed_string, @sig, @public_key).should be_false end end