├── .gitignore ├── OAuthConsumer_Prefix.pch ├── Crypto ├── sha1.h ├── hmac.h ├── Base64Transcoder.h ├── hmac.c ├── sha1.c └── Base64Transcoder.c ├── README ├── Categories ├── NSURL+Base.h ├── NSString+URLEncoding.h ├── NSURL+Base.m ├── NSMutableURLRequest+Parameters.h ├── NSString+URLEncoding.m └── NSMutableURLRequest+Parameters.m ├── OAProblem.h ├── OAPlaintextSignatureProvider.h ├── OAHMAC_SHA1SignatureProvider.h ├── OASignatureProviding.h ├── OATestServer.rb ├── OAPlaintextSignatureProvider.m ├── OAConsumer.h ├── OAuthConsumer.h ├── OACall.h ├── OADataFetcher.h ├── OAServiceTicket.h ├── OARequestParameter.h ├── OAConsumer.m ├── OAServiceTicket.m ├── OATokenManager.h ├── OAMutableURLRequest.h ├── OARequestParameter.m ├── OAHMAC_SHA1SignatureProvider.m ├── OAToken.h ├── OADataFetcher.m ├── OAProblem.m ├── OACall.m ├── OAMutableURLRequest.m ├── OAToken.m ├── OATokenManager.m └── OAuthConsumer.xcodeproj └── project.pbxproj /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.swp 3 | *~.nib 4 | 5 | build/ 6 | 7 | *.pbxuser 8 | *.perspective 9 | *.perspectivev3 10 | *.mode1v3 11 | 12 | -------------------------------------------------------------------------------- /OAuthConsumer_Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'CocoaTouchStaticLibrary' target in the 'CocoaTouchStaticLibrary' project. 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #endif 8 | -------------------------------------------------------------------------------- /Crypto/sha1.h: -------------------------------------------------------------------------------- 1 | 2 | // From http://www.mirrors.wiretapped.net/security/cryptography/hashes/sha1/sha1.c 3 | 4 | typedef struct { 5 | unsigned long state[5]; 6 | unsigned long count[2]; 7 | unsigned char buffer[64]; 8 | } SHA1_CTX; 9 | 10 | extern void SHA1Init(SHA1_CTX* context); 11 | extern void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int len); 12 | extern void SHA1Final(unsigned char digest[20], SHA1_CTX* context); 13 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | This is an iPhone ready version of: 2 | http://oauth.googlecode.com/svn/code/obj-c/OAuthConsumer/ 3 | 4 | "iPhone ready" simply means you just need to add the files to Xcode, and import "OAuthConsumer.h". 5 | 6 | If you're rolling with the iPhone: 7 | 8 | 1) Be sure to add Security.framework. 9 | 2) Include libxml2.dylib in your frameworks. You also need to add a 10 | build property to the project -- "header search paths" needs to 11 | include "$SDKROOT/usr/include/libxml2" with "Recursive" checked. 12 | 13 | Questions? E-mail me. jonathan at my initials (jdg) dot net. -------------------------------------------------------------------------------- /Categories/NSURL+Base.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSURL+Base.h 3 | // OAuthConsumer 4 | // 5 | // Created by Jon Crosby on 10/19/07. 6 | // Copyright 2007 Kaboomerang LLC. All rights reserved. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in 16 | // all copies or substantial portions of the Software. 17 | // 18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | // THE SOFTWARE. 25 | 26 | 27 | #import 28 | 29 | 30 | @interface NSURL (OABaseAdditions) 31 | 32 | - (NSString *)URLStringWithoutQuery; 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /OAProblem.h: -------------------------------------------------------------------------------- 1 | // 2 | // OAProblem.h 3 | // OAuthConsumer 4 | // 5 | // Created by Alberto García Hierro on 03/09/08. 6 | // Copyright 2008 Alberto García Hierro. All rights reserved. 7 | // bynotes.com 8 | 9 | #import 10 | 11 | enum { 12 | kOAProblemSignatureMethodRejected = 0, 13 | kOAProblemParameterAbsent, 14 | kOAProblemVersionRejected, 15 | kOAProblemConsumerKeyUnknown, 16 | kOAProblemTokenRejected, 17 | kOAProblemSignatureInvalid, 18 | kOAProblemNonceUsed, 19 | kOAProblemTimestampRefused, 20 | kOAProblemTokenExpired, 21 | kOAProblemTokenNotRenewable 22 | }; 23 | 24 | @interface OAProblem : NSObject { 25 | const NSString *problem; 26 | } 27 | 28 | @property (readonly) const NSString *problem; 29 | 30 | - (id)initWithProblem:(const NSString *)aProblem; 31 | - (id)initWithResponseBody:(const NSString *)response; 32 | 33 | - (BOOL)isEqualToProblem:(OAProblem *)aProblem; 34 | - (BOOL)isEqualToString:(const NSString *)aProblem; 35 | - (BOOL)isEqualTo:(id)aProblem; 36 | - (int)code; 37 | 38 | + (OAProblem *)problemWithResponseBody:(const NSString *)response; 39 | 40 | + (const NSArray *)validProblems; 41 | 42 | + (OAProblem *)SignatureMethodRejected; 43 | + (OAProblem *)ParameterAbsent; 44 | + (OAProblem *)VersionRejected; 45 | + (OAProblem *)ConsumerKeyUnknown; 46 | + (OAProblem *)TokenRejected; 47 | + (OAProblem *)SignatureInvalid; 48 | + (OAProblem *)NonceUsed; 49 | + (OAProblem *)TimestampRefused; 50 | + (OAProblem *)TokenExpired; 51 | + (OAProblem *)TokenNotRenewable; 52 | 53 | @end 54 | -------------------------------------------------------------------------------- /OAPlaintextSignatureProvider.h: -------------------------------------------------------------------------------- 1 | // 2 | // OAPlaintextSignatureProvider.h 3 | // OAuthConsumer 4 | // 5 | // Created by Jon Crosby on 10/19/07. 6 | // Copyright 2007 Kaboomerang LLC. All rights reserved. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in 16 | // all copies or substantial portions of the Software. 17 | // 18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | // THE SOFTWARE. 25 | 26 | 27 | #import 28 | #import "OASignatureProviding.h" 29 | 30 | @interface OAPlaintextSignatureProvider : NSObject 31 | @end 32 | -------------------------------------------------------------------------------- /OAHMAC_SHA1SignatureProvider.h: -------------------------------------------------------------------------------- 1 | // 2 | // OAHMAC_SHA1SignatureProvider.h 3 | // OAuthConsumer 4 | // 5 | // Created by Jon Crosby on 10/19/07. 6 | // Copyright 2007 Kaboomerang LLC. All rights reserved. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in 16 | // all copies or substantial portions of the Software. 17 | // 18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | // THE SOFTWARE. 25 | 26 | 27 | #import 28 | #import "OASignatureProviding.h" 29 | 30 | 31 | @interface OAHMAC_SHA1SignatureProvider : NSObject 32 | @end 33 | -------------------------------------------------------------------------------- /OASignatureProviding.h: -------------------------------------------------------------------------------- 1 | // 2 | // OASignatureProviding.h 3 | // 4 | // Created by Jon Crosby on 10/19/07. 5 | // Copyright 2007 Kaboomerang LLC. All rights reserved. 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files (the "Software"), to deal 9 | // in the Software without restriction, including without limitation the rights 10 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | // copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in 15 | // all copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | // THE SOFTWARE. 24 | 25 | 26 | #import 27 | 28 | 29 | @protocol OASignatureProviding 30 | 31 | - (NSString *)name; 32 | - (NSString *)signClearText:(NSString *)text withSecret:(NSString *)secret; 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /Crypto/hmac.h: -------------------------------------------------------------------------------- 1 | // 2 | // hmac.h 3 | // OAuthConsumer 4 | // 5 | // Created by Jonathan Wight on 4/8/8. 6 | // Copyright 2008 Jonathan Wight. All rights reserved. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in 16 | // all copies or substantial portions of the Software. 17 | // 18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | // THE SOFTWARE. 25 | 26 | #ifndef HMAC_H 27 | #define HMAC_H 1 28 | 29 | extern void hmac_sha1(const unsigned char *inText, int inTextLength, unsigned char* inKey, const unsigned int inKeyLength, unsigned char *outDigest); 30 | 31 | #endif /* HMAC_H */ 32 | -------------------------------------------------------------------------------- /OATestServer.rb: -------------------------------------------------------------------------------- 1 | # 2 | # OATestServer.rb 3 | # OAuthConsumer 4 | # 5 | # Created by Jon Crosby on 10/19/07. 6 | # Copyright 2007 Kaboomerang LLC. All rights reserved. 7 | # 8 | # Permission is hereby granted, free of charge, to any person obtaining a copy 9 | # of this software and associated documentation files (the "Software"), to deal 10 | # in the Software without restriction, including without limitation the rights 11 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | # copies of the Software, and to permit persons to whom the Software is 13 | # furnished to do so, subject to the following conditions: 14 | # 15 | # The above copyright notice and this permission notice shall be included in 16 | # all copies or substantial portions of the Software. 17 | # 18 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | # THE SOFTWARE. 25 | 26 | # Note: Before running this, install Sinatra: http://sinatra.rubyforge.org/ 27 | 28 | require 'rubygems' 29 | require 'sinatra' 30 | 31 | get '/' do 32 | "Testing..." 33 | end 34 | 35 | post '/request_token' do 36 | "oauth_token=nnch734d00sl2jdk&oauth_token_secret=pfkkdhi9sl3r4s00" 37 | end -------------------------------------------------------------------------------- /Categories/NSString+URLEncoding.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+URLEncoding.h 3 | // 4 | // Created by Jon Crosby on 10/19/07. 5 | // Copyright 2007 Kaboomerang LLC. All rights reserved. 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files (the "Software"), to deal 9 | // in the Software without restriction, including without limitation the rights 10 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | // copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in 15 | // all copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | // THE SOFTWARE. 24 | 25 | 26 | #import 27 | 28 | 29 | @interface NSString (OAURLEncodingAdditions) 30 | 31 | - (NSString *)encodedURLString; 32 | - (NSString *)encodedURLParameterString; 33 | - (NSString *)decodedURLString; 34 | - (NSString *)removeQuotes; 35 | @end 36 | -------------------------------------------------------------------------------- /Categories/NSURL+Base.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSURL+Base.m 3 | // OAuthConsumer 4 | // 5 | // Created by Jon Crosby on 10/19/07. 6 | // Copyright 2007 Kaboomerang LLC. All rights reserved. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in 16 | // all copies or substantial portions of the Software. 17 | // 18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | // THE SOFTWARE. 25 | 26 | 27 | #import "NSURL+Base.h" 28 | 29 | 30 | @implementation NSURL (OABaseAdditions) 31 | 32 | - (NSString *)URLStringWithoutQuery { 33 | NSArray *parts = [[self absoluteString] componentsSeparatedByString:@"?"]; 34 | return [parts objectAtIndex:0]; 35 | } 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /OAPlaintextSignatureProvider.m: -------------------------------------------------------------------------------- 1 | // 2 | // OAPlaintextSignatureProvider.m 3 | // OAuthConsumer 4 | // 5 | // Created by Jon Crosby on 10/19/07. 6 | // Copyright 2007 Kaboomerang LLC. All rights reserved. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in 16 | // all copies or substantial portions of the Software. 17 | // 18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | // THE SOFTWARE. 25 | 26 | 27 | #import "OAPlaintextSignatureProvider.h" 28 | 29 | 30 | @implementation OAPlaintextSignatureProvider 31 | 32 | - (NSString *)name { 33 | return @"PLAINTEXT"; 34 | } 35 | 36 | - (NSString *)signClearText:(NSString *)text withSecret:(NSString *)secret { 37 | return secret; 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /OAConsumer.h: -------------------------------------------------------------------------------- 1 | // 2 | // OAConsumer.h 3 | // OAuthConsumer 4 | // 5 | // Created by Jon Crosby on 10/19/07. 6 | // Copyright 2007 Kaboomerang LLC. All rights reserved. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in 16 | // all copies or substantial portions of the Software. 17 | // 18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | // THE SOFTWARE. 25 | 26 | 27 | #import 28 | 29 | 30 | @interface OAConsumer : NSObject { 31 | @protected 32 | NSString *key; 33 | NSString *secret; 34 | } 35 | @property(copy, readwrite) NSString *key; 36 | @property(copy, readwrite) NSString *secret; 37 | 38 | - (id)initWithKey:(const NSString *)aKey secret:(const NSString *)aSecret; 39 | 40 | - (BOOL)isEqualToConsumer:(OAConsumer *)aConsumer; 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /Categories/NSMutableURLRequest+Parameters.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSMutableURLRequest+Parameters.h 3 | // 4 | // Created by Jon Crosby on 10/19/07. 5 | // Copyright 2007 Kaboomerang LLC. All rights reserved. 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files (the "Software"), to deal 9 | // in the Software without restriction, including without limitation the rights 10 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | // copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in 15 | // all copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | // THE SOFTWARE. 24 | 25 | #import 26 | #import "OARequestParameter.h" 27 | #import "NSURL+Base.h" 28 | 29 | 30 | @interface NSMutableURLRequest (OAParameterAdditions) 31 | 32 | @property(nonatomic, retain) NSArray *parameters; 33 | 34 | - (void)setHTTPBodyWithString:(NSString *)body; 35 | - (void)attachFileWithName:(NSString *)name filename:(NSString*)filename contentType:(NSString *)contentType data:(NSData*)data; 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /Crypto/Base64Transcoder.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Base64Transcoder.h 3 | * Base64Test 4 | * 5 | * Created by Jonathan Wight on Tue Mar 18 2003. 6 | * Copyright (c) 2003 Toxic Software. All rights reserved. 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a copy 9 | * of this software and associated documentation files (the "Software"), to deal 10 | * in the Software without restriction, including without limitation the rights 11 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the Software is 13 | * furnished to do so, subject to the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included in 16 | * all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | * THE SOFTWARE. 25 | * 26 | */ 27 | 28 | #include 29 | #include 30 | 31 | extern size_t EstimateBas64EncodedDataSize(size_t inDataSize); 32 | extern size_t EstimateBas64DecodedDataSize(size_t inDataSize); 33 | 34 | extern bool Base64EncodeData(const void *inInputData, size_t inInputDataSize, char *outOutputData, size_t *ioOutputDataSize); 35 | extern bool Base64DecodeData(const void *inInputData, size_t inInputDataSize, void *ioOutputData, size_t *ioOutputDataSize); 36 | 37 | -------------------------------------------------------------------------------- /OAuthConsumer.h: -------------------------------------------------------------------------------- 1 | // 2 | // OAuthConsumer.h 3 | // OAuthConsumer 4 | // 5 | // Created by Jon Crosby on 10/19/07. 6 | // Copyright 2007 Kaboomerang LLC. All rights reserved. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in 16 | // all copies or substantial portions of the Software. 17 | // 18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | // THE SOFTWARE. 25 | 26 | #import 27 | #import "OAProblem.h" 28 | #import "OAToken.h" 29 | #import "OAConsumer.h" 30 | #import "OAMutableURLRequest.h" 31 | #import "NSString+URLEncoding.h" 32 | #import "NSMutableURLRequest+Parameters.h" 33 | #import "NSURL+Base.h" 34 | #import "OASignatureProviding.h" 35 | #import "OAHMAC_SHA1SignatureProvider.h" 36 | #import "OAPlaintextSignatureProvider.h" 37 | #import "OARequestParameter.h" 38 | #import "OAServiceTicket.h" 39 | #import "OADataFetcher.h" 40 | #import "OATokenManager.h" -------------------------------------------------------------------------------- /OACall.h: -------------------------------------------------------------------------------- 1 | // 2 | // OACall.h 3 | // OAuthConsumer 4 | // 5 | // Created by Alberto García Hierro on 04/09/08. 6 | // Copyright 2008 Alberto García Hierro. All rights reserved. 7 | // bynotes.com 8 | 9 | #import 10 | 11 | @class OAProblem; 12 | @class OACall; 13 | 14 | @protocol OACallDelegate 15 | 16 | - (void)call:(OACall *)call failedWithError:(NSError *)error; 17 | - (void)call:(OACall *)call failedWithProblem:(OAProblem *)problem; 18 | 19 | @end 20 | 21 | @class OAConsumer; 22 | @class OAToken; 23 | @class OADataFetcher; 24 | @class OAMutableURLRequest; 25 | @class OAServiceTicket; 26 | 27 | @interface OACall : NSObject { 28 | NSURL *url; 29 | NSString *method; 30 | NSArray *parameters; 31 | NSDictionary *files; 32 | NSObject *delegate; 33 | SEL finishedSelector; 34 | OADataFetcher *fetcher; 35 | OAMutableURLRequest *request; 36 | OAServiceTicket *ticket; 37 | } 38 | 39 | @property(readonly) NSURL *url; 40 | @property(readonly) NSString *method; 41 | @property(readonly) NSArray *parameters; 42 | @property(readonly) NSDictionary *files; 43 | @property(nonatomic, retain) OAServiceTicket *ticket; 44 | 45 | - (id)init; 46 | - (id)initWithURL:(NSURL *)aURL; 47 | - (id)initWithURL:(NSURL *)aURL method:(NSString *)aMethod; 48 | - (id)initWithURL:(NSURL *)aURL parameters:(NSArray *)theParameters; 49 | - (id)initWithURL:(NSURL *)aURL method:(NSString *)aMethod parameters:(NSArray *)theParameters; 50 | - (id)initWithURL:(NSURL *)aURL parameters:(NSArray *)theParameters files:(NSDictionary*)theFiles; 51 | 52 | - (id)initWithURL:(NSURL *)aURL 53 | method:(NSString *)aMethod 54 | parameters:(NSArray *)theParameters 55 | files:(NSDictionary*)theFiles; 56 | 57 | - (void)perform:(OAConsumer *)consumer 58 | token:(OAToken *)token 59 | realm:(NSString *)realm 60 | delegate:(NSObject *)aDelegate 61 | didFinish:(SEL)finished; 62 | 63 | @end 64 | -------------------------------------------------------------------------------- /OADataFetcher.h: -------------------------------------------------------------------------------- 1 | // 2 | // OADataFetcher.h 3 | // OAuthConsumer 4 | // 5 | // Created by Jon Crosby on 11/5/07. 6 | // Copyright 2007 Kaboomerang LLC. All rights reserved. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in 16 | // all copies or substantial portions of the Software. 17 | // 18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | // THE SOFTWARE. 25 | 26 | #import 27 | #import "OAMutableURLRequest.h" 28 | #import "OAServiceTicket.h" 29 | 30 | 31 | @interface OADataFetcher : NSObject { 32 | @private 33 | OAMutableURLRequest *request; 34 | NSURLResponse *response; 35 | NSURLConnection *connection; 36 | NSMutableData *responseData; 37 | id delegate; 38 | SEL didFinishSelector; 39 | SEL didFailSelector; 40 | } 41 | 42 | @property (nonatomic, assign) id delegate; 43 | 44 | - (void)fetchDataWithRequest:(OAMutableURLRequest *)aRequest delegate:(id)aDelegate didFinishSelector:(SEL)finishSelector didFailSelector:(SEL)failSelector; 45 | 46 | @end 47 | -------------------------------------------------------------------------------- /OAServiceTicket.h: -------------------------------------------------------------------------------- 1 | // 2 | // OAServiceTicket.h 3 | // OAuthConsumer 4 | // 5 | // Created by Jon Crosby on 11/5/07. 6 | // Copyright 2007 Kaboomerang LLC. All rights reserved. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in 16 | // all copies or substantial portions of the Software. 17 | // 18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | // THE SOFTWARE. 25 | 26 | 27 | #import 28 | #import "OAMutableURLRequest.h" 29 | 30 | 31 | @interface OAServiceTicket : NSObject { 32 | @private 33 | OAMutableURLRequest *request; 34 | NSURLResponse *response; 35 | NSData *data; 36 | BOOL didSucceed; 37 | } 38 | @property(readonly) OAMutableURLRequest *request; 39 | @property(readonly) NSURLResponse *response; 40 | @property(readonly) NSData *data; 41 | @property(readonly) BOOL didSucceed; 42 | @property(readonly) NSString *body; 43 | 44 | - (id)initWithRequest:(OAMutableURLRequest *)aRequest response:(NSURLResponse *)aResponse data:(NSData *)aData didSucceed:(BOOL)success; 45 | 46 | @end 47 | -------------------------------------------------------------------------------- /OARequestParameter.h: -------------------------------------------------------------------------------- 1 | // 2 | // OARequestParameter.h 3 | // OAuthConsumer 4 | // 5 | // Created by Jon Crosby on 10/19/07. 6 | // Copyright 2007 Kaboomerang LLC. All rights reserved. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in 16 | // all copies or substantial portions of the Software. 17 | // 18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | // THE SOFTWARE. 25 | 26 | 27 | #import 28 | #import "NSString+URLEncoding.h" 29 | 30 | 31 | @interface OARequestParameter : NSObject { 32 | @protected 33 | NSString *name; 34 | NSString *value; 35 | } 36 | @property(copy, readwrite) NSString *name; 37 | @property(copy, readwrite) NSString *value; 38 | 39 | - (id)initWithName:(NSString *)aName value:(NSString *)aValue; 40 | - (NSString *)URLEncodedName; 41 | - (NSString *)URLEncodedValue; 42 | - (NSString *)URLEncodedNameValuePair; 43 | 44 | - (BOOL)isEqualToRequestParameter:(OARequestParameter *)parameter; 45 | 46 | + (id)requestParameter:(NSString *)aName value:(NSString *)aValue; 47 | 48 | @end 49 | -------------------------------------------------------------------------------- /OAConsumer.m: -------------------------------------------------------------------------------- 1 | // 2 | // OAConsumer.m 3 | // OAuthConsumer 4 | // 5 | // Created by Jon Crosby on 10/19/07. 6 | // Copyright 2007 Kaboomerang LLC. All rights reserved. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in 16 | // all copies or substantial portions of the Software. 17 | // 18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | // THE SOFTWARE. 25 | 26 | #import "OAConsumer.h" 27 | 28 | 29 | @implementation OAConsumer 30 | @synthesize key, secret; 31 | 32 | #pragma mark init 33 | 34 | - (id)initWithKey:(const NSString *)aKey secret:(const NSString *)aSecret { 35 | [super init]; 36 | self.key = [aKey retain]; 37 | self.secret = [aSecret retain]; 38 | return self; 39 | } 40 | 41 | - (BOOL)isEqual:(id)object { 42 | if ([object isKindOfClass:[self class]]) { 43 | return [self isEqualToConsumer:(OAConsumer*)object]; 44 | } 45 | return NO; 46 | } 47 | 48 | - (BOOL)isEqualToConsumer:(OAConsumer *)aConsumer { 49 | return ([self.key isEqualToString:aConsumer.key] && 50 | [self.secret isEqualToString:aConsumer.secret]); 51 | } 52 | 53 | @end 54 | -------------------------------------------------------------------------------- /OAServiceTicket.m: -------------------------------------------------------------------------------- 1 | // 2 | // OAServiceTicket.m 3 | // OAuthConsumer 4 | // 5 | // Created by Jon Crosby on 11/5/07. 6 | // Copyright 2007 Kaboomerang LLC. All rights reserved. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in 16 | // all copies or substantial portions of the Software. 17 | // 18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | // THE SOFTWARE. 25 | 26 | 27 | #import "OAServiceTicket.h" 28 | 29 | 30 | @implementation OAServiceTicket 31 | @synthesize request, response, data, didSucceed; 32 | 33 | - (id)initWithRequest:(OAMutableURLRequest *)aRequest response:(NSURLResponse *)aResponse data:(NSData *)aData didSucceed:(BOOL)success { 34 | [super init]; 35 | request = aRequest; 36 | response = aResponse; 37 | data = aData; 38 | didSucceed = success; 39 | return self; 40 | } 41 | 42 | - (NSString *)body 43 | { 44 | if (!data) { 45 | return nil; 46 | } 47 | 48 | return [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease]; 49 | } 50 | 51 | - (NSString *)description { 52 | return [NSString stringWithFormat:@"", [self body]]; 53 | } 54 | 55 | @end 56 | -------------------------------------------------------------------------------- /OATokenManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // OATokenManager.h 3 | // OAuthConsumer 4 | // 5 | // Created by Alberto García Hierro on 01/09/08. 6 | // Copyright 2008 Alberto García Hierro. All rights reserved. 7 | // bynotes.com 8 | 9 | #import 10 | 11 | #import "OACall.h" 12 | 13 | @class OATokenManager; 14 | 15 | @protocol OATokenManagerDelegate 16 | 17 | - (BOOL)tokenManager:(OATokenManager *)manager failedCall:(OACall *)call withError:(NSError *)error; 18 | - (BOOL)tokenManager:(OATokenManager *)manager failedCall:(OACall *)call withProblem:(OAProblem *)problem; 19 | 20 | @optional 21 | 22 | - (BOOL)tokenManagerNeedsToken:(OATokenManager *)manager; 23 | 24 | @end 25 | 26 | @class OAConsumer; 27 | @class OAToken; 28 | 29 | @interface OATokenManager : NSObject { 30 | OAConsumer *consumer; 31 | OAToken *acToken; 32 | OAToken *reqToken; 33 | OAToken *initialToken; 34 | NSString *authorizedTokenKey; 35 | NSString *oauthBase; 36 | NSString *realm; 37 | NSString *callback; 38 | NSObject *delegate; 39 | NSMutableArray *calls; 40 | NSMutableArray *selectors; 41 | NSMutableDictionary *delegates; 42 | BOOL isDispatching; 43 | } 44 | 45 | 46 | - (id)init; 47 | 48 | - (id)initWithConsumer:(OAConsumer *)aConsumer token:(OAToken *)aToken oauthBase:(const NSString *)base 49 | realm:(const NSString *)aRealm callback:(const NSString *)aCallback 50 | delegate:(NSObject *)aDelegate; 51 | 52 | - (void)authorizedToken:(const NSString *)key; 53 | 54 | - (void)fetchData:(NSString *)aURL finished:(SEL)didFinish; 55 | 56 | - (void)fetchData:(NSString *)aURL method:(NSString *)aMethod parameters:(NSArray *)theParameters 57 | finished:(SEL)didFinish; 58 | 59 | - (void)fetchData:(NSString *)aURL method:(NSString *)aMethod parameters:(NSArray *)theParameters 60 | files:(NSDictionary *)theFiles finished:(SEL)didFinish; 61 | 62 | - (void)fetchData:(NSString *)aURL method:(NSString *)aMethod parameters:(NSArray *)theParameters 63 | files:(NSDictionary *)theFiles finished:(SEL)didFinish delegate:(NSObject*)aDelegate; 64 | 65 | - (void)call:(OACall *)call failedWithError:(NSError *)error; 66 | - (void)call:(OACall *)call failedWithProblem:(OAProblem *)problem; 67 | 68 | @end 69 | -------------------------------------------------------------------------------- /OAMutableURLRequest.h: -------------------------------------------------------------------------------- 1 | // 2 | // OAMutableURLRequest.h 3 | // OAuthConsumer 4 | // 5 | // Created by Jon Crosby on 10/19/07. 6 | // Copyright 2007 Kaboomerang LLC. All rights reserved. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in 16 | // all copies or substantial portions of the Software. 17 | // 18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | // THE SOFTWARE. 25 | 26 | 27 | #import 28 | #import "OAConsumer.h" 29 | #import "OAToken.h" 30 | #import "OAHMAC_SHA1SignatureProvider.h" 31 | #import "OASignatureProviding.h" 32 | #import "NSMutableURLRequest+Parameters.h" 33 | #import "NSURL+Base.h" 34 | 35 | 36 | @interface OAMutableURLRequest : NSMutableURLRequest { 37 | @protected 38 | OAConsumer *consumer; 39 | OAToken *token; 40 | NSString *realm; 41 | NSString *signature; 42 | id signatureProvider; 43 | NSString *nonce; 44 | NSString *timestamp; 45 | } 46 | @property(readonly) NSString *signature; 47 | @property(readonly) NSString *nonce; 48 | 49 | - (id)initWithURL:(NSURL *)aUrl 50 | consumer:(OAConsumer *)aConsumer 51 | token:(OAToken *)aToken 52 | realm:(NSString *)aRealm 53 | signatureProvider:(id)aProvider; 54 | 55 | - (id)initWithURL:(NSURL *)aUrl 56 | consumer:(OAConsumer *)aConsumer 57 | token:(OAToken *)aToken 58 | realm:(NSString *)aRealm 59 | signatureProvider:(id)aProvider 60 | nonce:(NSString *)aNonce 61 | timestamp:(NSString *)aTimestamp; 62 | 63 | - (void)prepare; 64 | 65 | @end 66 | -------------------------------------------------------------------------------- /OARequestParameter.m: -------------------------------------------------------------------------------- 1 | // 2 | // OARequestParameter.m 3 | // OAuthConsumer 4 | // 5 | // Created by Jon Crosby on 10/19/07. 6 | // Copyright 2007 Kaboomerang LLC. All rights reserved. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in 16 | // all copies or substantial portions of the Software. 17 | // 18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | // THE SOFTWARE. 25 | 26 | 27 | #import "OARequestParameter.h" 28 | 29 | 30 | @implementation OARequestParameter 31 | @synthesize name, value; 32 | 33 | - (id)initWithName:(NSString *)aName value:(NSString *)aValue { 34 | [super init]; 35 | self.name = aName; 36 | self.value = aValue; 37 | return self; 38 | } 39 | 40 | - (NSString *)URLEncodedName { 41 | return self.name; 42 | // return [self.name encodedURLParameterString]; 43 | } 44 | 45 | - (NSString *)URLEncodedValue { 46 | return [self.value encodedURLParameterString]; 47 | } 48 | 49 | - (NSString *)URLEncodedNameValuePair { 50 | return [NSString stringWithFormat:@"%@=%@", [self URLEncodedName], [self URLEncodedValue]]; 51 | } 52 | 53 | - (BOOL)isEqual:(id)object { 54 | if ([object isKindOfClass:[self class]]) { 55 | return [self isEqualToRequestParameter:(OARequestParameter *)object]; 56 | } 57 | 58 | return NO; 59 | } 60 | 61 | - (BOOL)isEqualToRequestParameter:(OARequestParameter *)parameter { 62 | return ([self.name isEqualToString:parameter.name] && 63 | [self.value isEqualToString:parameter.value]); 64 | } 65 | 66 | 67 | + (id)requestParameter:(NSString *)aName value:(NSString *)aValue 68 | { 69 | return [[[self alloc] initWithName:aName value:aValue] autorelease]; 70 | } 71 | 72 | - (void)dealloc{ 73 | [name release]; 74 | [value release]; 75 | [super dealloc]; 76 | } 77 | @end 78 | -------------------------------------------------------------------------------- /OAHMAC_SHA1SignatureProvider.m: -------------------------------------------------------------------------------- 1 | // 2 | // OAHMAC_SHA1SignatureProvider.m 3 | // OAuthConsumer 4 | // 5 | // Created by Jon Crosby on 10/19/07. 6 | // Copyright 2007 Kaboomerang LLC. All rights reserved. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in 16 | // all copies or substantial portions of the Software. 17 | // 18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | // THE SOFTWARE. 25 | 26 | 27 | #import "OAHMAC_SHA1SignatureProvider.h" 28 | 29 | // #include "hmac.h" 30 | #include "Base64Transcoder.h" 31 | 32 | #import 33 | #import 34 | 35 | @implementation OAHMAC_SHA1SignatureProvider 36 | 37 | - (NSString *)name { 38 | return @"HMAC-SHA1"; 39 | } 40 | 41 | - (NSString *)signClearText:(NSString *)text withSecret:(NSString *)secret { 42 | NSData *secretData = [secret dataUsingEncoding:NSUTF8StringEncoding]; 43 | NSData *clearTextData = [text dataUsingEncoding:NSUTF8StringEncoding]; 44 | unsigned char result[CC_SHA1_DIGEST_LENGTH]; 45 | 46 | // hmac_sha1((unsigned char *)[clearTextData bytes], [clearTextData length], (unsigned char *)[secretData bytes], [secretData length], result); 47 | 48 | CCHmac(kCCHmacAlgSHA1, (const void *)[secretData bytes], [secretData length], (const void *)[clearTextData bytes], [clearTextData length], result); 49 | 50 | //Base64 Encoding 51 | 52 | char base64Result[32]; 53 | size_t theResultLength = 32; 54 | Base64EncodeData(result, 20, base64Result, &theResultLength); 55 | NSData *theData = [NSData dataWithBytes:base64Result length:theResultLength]; 56 | 57 | NSString *base64EncodedResult = [[[NSString alloc] initWithData:theData encoding:NSUTF8StringEncoding] autorelease]; 58 | 59 | return base64EncodedResult; 60 | } 61 | 62 | @end 63 | -------------------------------------------------------------------------------- /OAToken.h: -------------------------------------------------------------------------------- 1 | // 2 | // OAToken.h 3 | // OAuthConsumer 4 | // 5 | // Created by Jon Crosby on 10/19/07. 6 | // Copyright 2007 Kaboomerang LLC. All rights reserved. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in 16 | // all copies or substantial portions of the Software. 17 | // 18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | // THE SOFTWARE. 25 | 26 | #import 27 | 28 | @interface OAToken : NSObject { 29 | @protected 30 | NSString *key; 31 | NSString *secret; 32 | NSString *verifier; 33 | NSString *session; 34 | NSNumber *duration; 35 | NSMutableDictionary *attributes; 36 | NSDate *created; 37 | BOOL renewable; 38 | BOOL forRenewal; 39 | } 40 | @property(retain, readwrite) NSString *key; 41 | @property(retain, readwrite) NSString *secret; 42 | @property(retain, readwrite) NSString *verifier; 43 | @property(retain, readwrite) NSString *session; 44 | @property(retain, readwrite) NSNumber *duration; 45 | @property(retain, readwrite) NSDictionary *attributes; 46 | @property(readwrite, getter=isForRenewal) BOOL forRenewal; 47 | 48 | - (id)initWithKey:(NSString *)aKey secret:(NSString *)aSecret; 49 | - (id)initWithKey:(NSString *)aKey secret:(NSString *)aSecret verifier:(NSString *)aVerifier session:(NSString *)aSession 50 | duration:(NSNumber *)aDuration attributes:(NSDictionary *)theAttributes created:(NSDate *)creation 51 | renewable:(BOOL)renew; 52 | - (id)initWithHTTPResponseBody:(NSString *)body; 53 | 54 | - (id)initWithUserDefaultsUsingServiceProviderName:(NSString *)provider prefix:(NSString *)prefix; 55 | - (int)storeInUserDefaultsWithServiceProviderName:(NSString *)provider prefix:(NSString *)prefix; 56 | 57 | - (BOOL)isValid; 58 | 59 | - (void)setAttribute:(NSString *)aKey value:(NSString *)aValue; 60 | - (NSString *)attribute:(NSString *)aKey; 61 | - (void)setAttributesWithString:(NSString *)aAttributes; 62 | - (NSString *)attributeString; 63 | 64 | - (BOOL)hasExpired; 65 | - (BOOL)isRenewable; 66 | - (void)setDurationWithString:(NSString *)aDuration; 67 | - (BOOL)hasAttributes; 68 | - (NSDictionary *)parameters; 69 | 70 | - (BOOL)isEqualToToken:(OAToken *)aToken; 71 | 72 | + (void)removeFromUserDefaultsWithServiceProviderName:(const NSString *)provider prefix:(const NSString *)prefix; 73 | 74 | @end 75 | -------------------------------------------------------------------------------- /Crypto/hmac.c: -------------------------------------------------------------------------------- 1 | // 2 | // hmac.c 3 | // OAuthConsumer 4 | // 5 | // Created by Jonathan Wight on 4/8/8. 6 | // Copyright 2008 Jonathan Wight. All rights reserved. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in 16 | // all copies or substantial portions of the Software. 17 | // 18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | // THE SOFTWARE. 25 | 26 | /* 27 | * Implementation of HMAC-SHA1. Adapted from example at http://tools.ietf.org/html/rfc2104 28 | 29 | */ 30 | 31 | #include "sha1.h" 32 | #include "hmac.h" 33 | 34 | #include 35 | #include 36 | 37 | void hmac_sha1(const unsigned char *inText, int inTextLength, unsigned char* inKey, const unsigned int inKeyLengthConst, unsigned char *outDigest) 38 | { 39 | const int B = 64; 40 | const size_t L = 20; 41 | 42 | SHA1_CTX theSHA1Context; 43 | unsigned char k_ipad[B + 1]; /* inner padding - key XORd with ipad */ 44 | unsigned char k_opad[B + 1]; /* outer padding - key XORd with opad */ 45 | 46 | /* if key is longer than 64 bytes reset it to key=SHA1 (key) */ 47 | unsigned int inKeyLength = inKeyLengthConst; 48 | if (inKeyLength > B) 49 | { 50 | SHA1Init(&theSHA1Context); 51 | SHA1Update(&theSHA1Context, inKey, inKeyLength); 52 | SHA1Final(inKey, &theSHA1Context); 53 | inKeyLength = L; 54 | } 55 | 56 | /* start out by storing key in pads */ 57 | memset(k_ipad, 0, sizeof k_ipad); 58 | memset(k_opad, 0, sizeof k_opad); 59 | memcpy(k_ipad, inKey, inKeyLength); 60 | memcpy(k_opad, inKey, inKeyLength); 61 | 62 | /* XOR key with ipad and opad values */ 63 | int i; 64 | for (i = 0; i < B; i++) 65 | { 66 | k_ipad[i] ^= 0x36; 67 | k_opad[i] ^= 0x5c; 68 | } 69 | 70 | /* 71 | * perform inner SHA1 72 | */ 73 | SHA1Init(&theSHA1Context); /* init context for 1st pass */ 74 | SHA1Update(&theSHA1Context, k_ipad, B); /* start with inner pad */ 75 | SHA1Update(&theSHA1Context, (unsigned char *)inText, inTextLength); /* then text of datagram */ 76 | SHA1Final((unsigned char *)outDigest, &theSHA1Context); /* finish up 1st pass */ 77 | 78 | /* 79 | * perform outer SHA1 80 | */ 81 | SHA1Init(&theSHA1Context); /* init context for 2nd 82 | * pass */ 83 | SHA1Update(&theSHA1Context, k_opad, B); /* start with outer pad */ 84 | SHA1Update(&theSHA1Context, outDigest, L); /* then results of 1st 85 | * hash */ 86 | SHA1Final(outDigest, &theSHA1Context); /* finish up 2nd pass */ 87 | 88 | } 89 | -------------------------------------------------------------------------------- /Categories/NSString+URLEncoding.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+URLEncoding.m 3 | // 4 | // Created by Jon Crosby on 10/19/07. 5 | // Copyright 2007 Kaboomerang LLC. All rights reserved. 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files (the "Software"), to deal 9 | // in the Software without restriction, including without limitation the rights 10 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | // copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in 15 | // all copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | // THE SOFTWARE. 24 | 25 | 26 | #import "NSString+URLEncoding.h" 27 | 28 | 29 | @implementation NSString (OAURLEncodingAdditions) 30 | 31 | - (NSString *)encodedURLString { 32 | NSString *result = (NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, 33 | (CFStringRef)self, 34 | NULL, // characters to leave unescaped (NULL = all escaped sequences are replaced) 35 | CFSTR("?=&+"), // legal URL characters to be escaped (NULL = all legal characters are replaced) 36 | kCFStringEncodingUTF8); // encoding 37 | return [result autorelease]; 38 | } 39 | 40 | - (NSString *)encodedURLParameterString { 41 | NSString *result = (NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, 42 | (CFStringRef)self, 43 | NULL, 44 | CFSTR(":/=,!$&'()*+;[]@#?"), 45 | kCFStringEncodingUTF8); 46 | return [result autorelease]; 47 | } 48 | 49 | - (NSString *)decodedURLString { 50 | NSString *result = (NSString*)CFURLCreateStringByReplacingPercentEscapesUsingEncoding(kCFAllocatorDefault, 51 | (CFStringRef)self, 52 | CFSTR(""), 53 | kCFStringEncodingUTF8); 54 | 55 | return [result autorelease]; 56 | 57 | } 58 | 59 | -(NSString *)removeQuotes 60 | { 61 | NSUInteger length = [self length]; 62 | NSString *ret = self; 63 | if ([self characterAtIndex:0] == '"') { 64 | ret = [ret substringFromIndex:1]; 65 | } 66 | if ([self characterAtIndex:length - 1] == '"') { 67 | ret = [ret substringToIndex:length - 2]; 68 | } 69 | 70 | return ret; 71 | } 72 | 73 | @end 74 | -------------------------------------------------------------------------------- /OADataFetcher.m: -------------------------------------------------------------------------------- 1 | // 2 | // OADataFetcher.m 3 | // OAuthConsumer 4 | // 5 | // Created by Jon Crosby on 11/5/07. 6 | // Copyright 2007 Kaboomerang LLC. All rights reserved. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in 16 | // all copies or substantial portions of the Software. 17 | // 18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | // THE SOFTWARE. 25 | 26 | 27 | #import "OADataFetcher.h" 28 | 29 | 30 | @implementation OADataFetcher 31 | 32 | 33 | @synthesize delegate; 34 | 35 | - (id)init { 36 | [super init]; 37 | responseData = [[NSMutableData alloc] init]; 38 | return self; 39 | } 40 | 41 | - (void)dealloc { 42 | [connection release]; 43 | [response release]; 44 | [responseData release]; 45 | [request release]; 46 | [super dealloc]; 47 | } 48 | 49 | /* Protocol for async URL loading */ 50 | - (void)connection:(NSURLConnection *)aConnection didReceiveResponse:(NSURLResponse *)aResponse { 51 | [response release]; 52 | response = [aResponse retain]; 53 | [responseData setLength:0]; 54 | } 55 | 56 | - (void)connection:(NSURLConnection *)aConnection didFailWithError:(NSError *)error { 57 | OAServiceTicket *ticket = [[OAServiceTicket alloc] initWithRequest:request 58 | response:response 59 | data:responseData 60 | didSucceed:NO]; 61 | [ticket autorelease]; 62 | [delegate performSelector:didFailSelector withObject:ticket withObject:error]; 63 | [ticket release], ticket = nil; 64 | } 65 | 66 | - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { 67 | [responseData appendData:data]; 68 | } 69 | 70 | - (void)connectionDidFinishLoading:(NSURLConnection *)connection { 71 | OAServiceTicket *ticket = [[OAServiceTicket alloc] initWithRequest:request 72 | response:response 73 | data:responseData 74 | didSucceed:[(NSHTTPURLResponse *)response statusCode] < 400]; 75 | [ticket autorelease]; 76 | [delegate performSelector:didFinishSelector withObject:ticket withObject:responseData]; 77 | [ticket release], ticket = nil; 78 | } 79 | 80 | - (void)fetchDataWithRequest:(OAMutableURLRequest *)aRequest delegate:(id)aDelegate didFinishSelector:(SEL)finishSelector didFailSelector:(SEL)failSelector { 81 | request = [aRequest retain]; 82 | delegate = aDelegate; 83 | didFinishSelector = finishSelector; 84 | didFailSelector = failSelector; 85 | 86 | [request prepare]; 87 | 88 | connection = [[NSURLConnection alloc] initWithRequest:aRequest delegate:self]; 89 | } 90 | 91 | @end 92 | -------------------------------------------------------------------------------- /OAProblem.m: -------------------------------------------------------------------------------- 1 | // 2 | // OAProblem.m 3 | // OAuthConsumer 4 | // 5 | // Created by Alberto García Hierro on 03/09/08. 6 | // Copyright 2008 Alberto García Hierro. All rights reserved. 7 | // bynotes.com 8 | 9 | #import "OAProblem.h" 10 | 11 | const NSString *signature_method_rejected = @"signature_method_rejected"; 12 | const NSString *parameter_absent = @"parameter_absent"; 13 | const NSString *version_rejected = @"version_rejected"; 14 | const NSString *consumer_key_unknown = @"consumer_key_unknown"; 15 | const NSString *token_rejected = @"token_rejected"; 16 | const NSString *signature_invalid = @"signature_invalid"; 17 | const NSString *nonce_used = @"nonce_used"; 18 | const NSString *timestamp_refused = @"timestamp_refused"; 19 | const NSString *token_expired = @"token_expired"; 20 | const NSString *token_not_renewable = @"token_not_renewable"; 21 | 22 | @implementation OAProblem 23 | 24 | @synthesize problem; 25 | 26 | - (id)initWithPointer:(const NSString *) aPointer 27 | { 28 | [super init]; 29 | problem = aPointer; 30 | return self; 31 | } 32 | 33 | - (id)initWithProblem:(const NSString *) aProblem 34 | { 35 | NSUInteger idx = [[OAProblem validProblems] indexOfObject:aProblem]; 36 | if (idx == NSNotFound) { 37 | return nil; 38 | } 39 | 40 | return [self initWithPointer: [[OAProblem validProblems] objectAtIndex:idx]]; 41 | } 42 | 43 | - (id)initWithResponseBody:(const NSString *) response 44 | { 45 | NSArray *fields = [response componentsSeparatedByString:@"&"]; 46 | for (NSString *field in fields) { 47 | if ([field hasPrefix:@"oauth_problem="]) { 48 | NSString *value = [[field componentsSeparatedByString:@"="] objectAtIndex:1]; 49 | return [self initWithProblem:value]; 50 | } 51 | } 52 | 53 | return nil; 54 | } 55 | 56 | + (OAProblem *)problemWithResponseBody:(const NSString *) response 57 | { 58 | return [[[OAProblem alloc] initWithResponseBody:response] autorelease]; 59 | } 60 | 61 | + (const NSArray *)validProblems 62 | { 63 | static NSArray *array; 64 | if (!array) { 65 | array = [[NSArray alloc] initWithObjects:signature_method_rejected, 66 | parameter_absent, 67 | version_rejected, 68 | consumer_key_unknown, 69 | token_rejected, 70 | signature_invalid, 71 | nonce_used, 72 | timestamp_refused, 73 | token_expired, 74 | token_not_renewable, 75 | nil]; 76 | } 77 | 78 | return array; 79 | } 80 | 81 | - (BOOL)isEqualToProblem:(OAProblem *) aProblem 82 | { 83 | return [problem isEqualToString:(NSString *)aProblem->problem]; 84 | } 85 | 86 | - (BOOL)isEqualToString:(const NSString *) aProblem 87 | { 88 | return [problem isEqualToString:(NSString *)aProblem]; 89 | } 90 | 91 | - (BOOL)isEqualTo:(id) aProblem 92 | { 93 | if ([aProblem isKindOfClass:[NSString class]]) { 94 | return [self isEqualToString:aProblem]; 95 | } 96 | 97 | if ([aProblem isKindOfClass:[OAProblem class]]) { 98 | return [self isEqualToProblem:aProblem]; 99 | } 100 | 101 | return NO; 102 | } 103 | 104 | - (int)code { 105 | return [[[self class] validProblems] indexOfObject:problem]; 106 | } 107 | 108 | - (NSString *)description 109 | { 110 | return [NSString stringWithFormat:@"OAuth Problem: %@", (NSString *)problem]; 111 | } 112 | 113 | #pragma mark class_methods 114 | 115 | + (OAProblem *)SignatureMethodRejected 116 | { 117 | return [[[OAProblem alloc] initWithPointer:signature_method_rejected] autorelease]; 118 | } 119 | 120 | + (OAProblem *)ParameterAbsent 121 | { 122 | return [[[OAProblem alloc] initWithPointer:parameter_absent] autorelease]; 123 | } 124 | 125 | + (OAProblem *)VersionRejected 126 | { 127 | return [[[OAProblem alloc] initWithPointer:version_rejected] autorelease]; 128 | } 129 | 130 | + (OAProblem *)ConsumerKeyUnknown 131 | { 132 | return [[[OAProblem alloc] initWithPointer:consumer_key_unknown] autorelease]; 133 | } 134 | 135 | + (OAProblem *)TokenRejected 136 | { 137 | return [[[OAProblem alloc] initWithPointer:token_rejected] autorelease]; 138 | } 139 | 140 | + (OAProblem *)SignatureInvalid 141 | { 142 | return [[[OAProblem alloc] initWithPointer:signature_invalid] autorelease]; 143 | } 144 | 145 | + (OAProblem *)NonceUsed 146 | { 147 | return [[[OAProblem alloc] initWithPointer:nonce_used] autorelease]; 148 | } 149 | 150 | + (OAProblem *)TimestampRefused 151 | { 152 | return [[[OAProblem alloc] initWithPointer:timestamp_refused] autorelease]; 153 | } 154 | 155 | + (OAProblem *)TokenExpired 156 | { 157 | return [[[OAProblem alloc] initWithPointer:token_expired] autorelease]; 158 | } 159 | 160 | + (OAProblem *)TokenNotRenewable 161 | { 162 | return [[[OAProblem alloc] initWithPointer:token_not_renewable] autorelease]; 163 | } 164 | 165 | @end 166 | -------------------------------------------------------------------------------- /OACall.m: -------------------------------------------------------------------------------- 1 | // 2 | // OACall.m 3 | // OAuthConsumer 4 | // 5 | // Created by Alberto García Hierro on 04/09/08. 6 | // Copyright 2008 Alberto García Hierro. All rights reserved. 7 | // bynotes.com 8 | 9 | #import "OAConsumer.h" 10 | #import "OAToken.h" 11 | #import "OAProblem.h" 12 | #import "OADataFetcher.h" 13 | #import "OAServiceTicket.h" 14 | #import "OAMutableURLRequest.h" 15 | #import "OACall.h" 16 | 17 | #import "NSMutableURLRequest+Parameters.h" 18 | 19 | @interface OACall (Private) 20 | 21 | - (void)callFinished:(OAServiceTicket *)ticket withData:(NSData *)data; 22 | - (void)callFailed:(OAServiceTicket *)ticket withError:(NSError *)error; 23 | 24 | @end 25 | 26 | @implementation OACall 27 | 28 | @synthesize url, method, parameters, files, ticket; 29 | 30 | - (id)init { 31 | return [self initWithURL:nil 32 | method:nil 33 | parameters:nil 34 | files:nil]; 35 | } 36 | 37 | - (id)initWithURL:(NSURL *)aURL { 38 | return [self initWithURL:aURL 39 | method:nil 40 | parameters:nil 41 | files:nil]; 42 | } 43 | 44 | - (id)initWithURL:(NSURL *)aURL method:(NSString *)aMethod { 45 | return [self initWithURL:aURL 46 | method:aMethod 47 | parameters:nil 48 | files:nil]; 49 | } 50 | 51 | - (id)initWithURL:(NSURL *)aURL parameters:(NSArray *)theParameters { 52 | return [self initWithURL:aURL 53 | method:nil 54 | parameters:theParameters]; 55 | } 56 | 57 | - (id)initWithURL:(NSURL *)aURL method:(NSString *)aMethod parameters:(NSArray *)theParameters { 58 | return [self initWithURL:aURL 59 | method:aMethod 60 | parameters:theParameters 61 | files:nil]; 62 | } 63 | 64 | - (id)initWithURL:(NSURL *)aURL parameters:(NSArray *)theParameters files:(NSDictionary*)theFiles { 65 | return [self initWithURL:aURL 66 | method:@"POST" 67 | parameters:theParameters 68 | files:theFiles]; 69 | } 70 | 71 | - (id)initWithURL:(NSURL *)aURL 72 | method:(NSString *)aMethod 73 | parameters:(NSArray *)theParameters 74 | files:(NSDictionary*)theFiles { 75 | url = [aURL retain]; 76 | method = [aMethod retain]; 77 | parameters = [theParameters retain]; 78 | files = [theFiles retain]; 79 | fetcher = nil; 80 | request = nil; 81 | 82 | return self; 83 | } 84 | 85 | - (void)dealloc { 86 | [url release]; 87 | [method release]; 88 | [parameters release]; 89 | [files release]; 90 | [fetcher release]; 91 | [request release]; 92 | [ticket release]; 93 | [super dealloc]; 94 | } 95 | 96 | - (void)callFailed:(OAServiceTicket *)aTicket withError:(NSError *)error { 97 | NSLog(@"error body: %@", aTicket.body); 98 | self.ticket = aTicket; 99 | [aTicket release]; 100 | OAProblem *problem = [OAProblem problemWithResponseBody:ticket.body]; 101 | if (problem) { 102 | [delegate call:self failedWithProblem:problem]; 103 | } else { 104 | [delegate call:self failedWithError:error]; 105 | } 106 | } 107 | 108 | - (void)callFinished:(OAServiceTicket *)aTicket withData:(NSData *)data { 109 | self.ticket = aTicket; 110 | [aTicket release]; 111 | if (ticket.didSucceed) { 112 | // NSLog(@"Call body: %@", ticket.body); 113 | [delegate performSelector:finishedSelector withObject:self withObject:ticket.body]; 114 | } else { 115 | // NSLog(@"Failed call body: %@", ticket.body); 116 | [self callFailed:[ticket retain] withError:nil]; 117 | } 118 | } 119 | 120 | - (void)perform:(OAConsumer *)consumer 121 | token:(OAToken *)token 122 | realm:(NSString *)realm 123 | delegate:(NSObject *)aDelegate 124 | didFinish:(SEL)finished 125 | 126 | { 127 | delegate = aDelegate; 128 | finishedSelector = finished; 129 | 130 | request = [[OAMutableURLRequest alloc] initWithURL:url 131 | consumer:consumer 132 | token:token 133 | realm:realm 134 | signatureProvider:nil]; 135 | if(method) { 136 | [request setHTTPMethod:method]; 137 | } 138 | 139 | if (self.parameters) { 140 | [request setParameters:self.parameters]; 141 | } 142 | 143 | // if (self.files) { 144 | // for (NSString *key in self.files) { 145 | // [request attachFileWithName:@"file" filename:NSLocalizedString(@"Photo.jpg", @"") data:[self.files objectForKey:key]]; 146 | // } 147 | // } 148 | 149 | fetcher = [[OADataFetcher alloc] init]; 150 | [fetcher fetchDataWithRequest:request 151 | delegate:self 152 | didFinishSelector:@selector(callFinished:withData:) 153 | didFailSelector:@selector(callFailed:withError:)]; 154 | } 155 | 156 | /*- (BOOL)isEqual:(id)object { 157 | if ([object isKindOfClass:[self class]]) { 158 | return [self isEqualToCall:(OACall *)object]; 159 | } 160 | return NO; 161 | } 162 | 163 | - (BOOL)isEqualToCall:(OACall *)aCall { 164 | return (delegate == aCall->delegate 165 | && finishedSelector == aCall->finishedSelector 166 | && [url isEqualTo:aCall.url] 167 | && [method isEqualToString:aCall.method] 168 | && [parameters isEqualToArray:aCall.parameters] 169 | && [files isEqualToDictionary:aCall.files]); 170 | }*/ 171 | 172 | @end 173 | -------------------------------------------------------------------------------- /Categories/NSMutableURLRequest+Parameters.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSMutableURLRequest+Parameters.m 3 | // 4 | // Created by Jon Crosby on 10/19/07. 5 | // Copyright 2007 Kaboomerang LLC. All rights reserved. 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files (the "Software"), to deal 9 | // in the Software without restriction, including without limitation the rights 10 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | // copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in 15 | // all copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | // THE SOFTWARE. 24 | 25 | 26 | #import "NSMutableURLRequest+Parameters.h" 27 | 28 | static NSString *Boundary = @"-----------------------------------0xCoCoaouTHeBouNDaRy"; 29 | 30 | @implementation NSMutableURLRequest (OAParameterAdditions) 31 | 32 | - (BOOL)isMultipart { 33 | return [[self valueForHTTPHeaderField:@"Content-Type"] hasPrefix:@"multipart/form-data"]; 34 | } 35 | 36 | - (NSArray *)parameters { 37 | NSString *encodedParameters = nil; 38 | 39 | if (![self isMultipart]) { 40 | if ([[self HTTPMethod] isEqualToString:@"GET"] || [[self HTTPMethod] isEqualToString:@"DELETE"]) { 41 | encodedParameters = [[self URL] query]; 42 | } else { 43 | encodedParameters = [[[NSString alloc] initWithData:[self HTTPBody] encoding:NSASCIIStringEncoding] autorelease]; 44 | } 45 | } 46 | 47 | if (encodedParameters == nil || [encodedParameters isEqualToString:@""]) { 48 | return nil; 49 | } 50 | // NSLog(@"raw parameters %@", encodedParameters); 51 | NSArray *encodedParameterPairs = [encodedParameters componentsSeparatedByString:@"&"]; 52 | NSMutableArray *requestParameters = [NSMutableArray arrayWithCapacity:[encodedParameterPairs count]]; 53 | 54 | for (NSString *encodedPair in encodedParameterPairs) { 55 | NSArray *encodedPairElements = [encodedPair componentsSeparatedByString:@"="]; 56 | OARequestParameter *parameter = [[OARequestParameter alloc] initWithName:[[encodedPairElements objectAtIndex:0] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding] 57 | value:[[encodedPairElements objectAtIndex:1] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]; 58 | [requestParameters addObject:parameter]; 59 | [parameter release], parameter = nil; 60 | } 61 | 62 | return requestParameters; 63 | } 64 | 65 | - (void)setParameters:(NSArray *)parameters 66 | { 67 | NSMutableArray *pairs = [[[NSMutableArray alloc] initWithCapacity:[parameters count]] autorelease]; 68 | for (OARequestParameter *requestParameter in parameters) { 69 | [pairs addObject:[requestParameter URLEncodedNameValuePair]]; 70 | } 71 | 72 | NSString *encodedParameterPairs = [pairs componentsJoinedByString:@"&"]; 73 | 74 | if ([[self HTTPMethod] isEqualToString:@"GET"] || [[self HTTPMethod] isEqualToString:@"DELETE"]) { 75 | [self setURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@?%@", [[self URL] URLStringWithoutQuery], encodedParameterPairs]]]; 76 | } else { 77 | // POST, PUT 78 | [self setHTTPBodyWithString:encodedParameterPairs]; 79 | [self setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"]; 80 | } 81 | } 82 | 83 | - (void)setHTTPBodyWithString:(NSString *)body { 84 | NSData *bodyData = [body dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]; 85 | [self setValue:[NSString stringWithFormat:@"%d", [bodyData length]] forHTTPHeaderField:@"Content-Length"]; 86 | [self setHTTPBody:bodyData]; 87 | } 88 | 89 | - (void)attachFileWithName:(NSString *)name filename:(NSString*)filename contentType:(NSString *)contentType data:(NSData*)data { 90 | 91 | NSArray *parameters = [self parameters]; 92 | [self setValue:[@"multipart/form-data; boundary=" stringByAppendingString:Boundary] forHTTPHeaderField:@"Content-type"]; 93 | 94 | NSMutableData *bodyData = [NSMutableData new]; 95 | for (OARequestParameter *parameter in parameters) { 96 | NSString *param = [NSString stringWithFormat:@"--%@\r\nContent-Disposition: form-data; name=\"%@\"\r\n\r\n%@\r\n", 97 | Boundary, [parameter URLEncodedName], [parameter value]]; 98 | 99 | [bodyData appendData:[param dataUsingEncoding:NSUTF8StringEncoding]]; 100 | } 101 | 102 | NSString *filePrefix = [NSString stringWithFormat:@"--%@\r\nContent-Disposition: form-data; name=\"%@\"; filename=\"%@\"\r\nContent-Type: %@\r\n\r\n", 103 | Boundary, name, filename, contentType]; 104 | [bodyData appendData:[filePrefix dataUsingEncoding:NSUTF8StringEncoding]]; 105 | [bodyData appendData:data]; 106 | 107 | [bodyData appendData:[[[@"--" stringByAppendingString:Boundary] stringByAppendingString:@"--"] dataUsingEncoding:NSUTF8StringEncoding]]; 108 | [self setValue:[NSString stringWithFormat:@"%d", [bodyData length]] forHTTPHeaderField:@"Content-Length"]; 109 | [self setHTTPBody:bodyData]; 110 | [bodyData release]; 111 | } 112 | 113 | @end 114 | -------------------------------------------------------------------------------- /Crypto/sha1.c: -------------------------------------------------------------------------------- 1 | /* 2 | SHA-1 in C 3 | By Steve Reid 4 | 100% Public Domain 5 | 6 | Test Vectors (from FIPS PUB 180-1) 7 | "abc" 8 | A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D 9 | "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" 10 | 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 11 | A million repetitions of "a" 12 | 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F 13 | */ 14 | 15 | /* #define LITTLE_ENDIAN * This should be #define'd if true. */ 16 | #if __LITTLE_ENDIAN__ 17 | #define LITTLE_ENDIAN 18 | #endif 19 | /* #define SHA1HANDSOFF * Copies data before messing with it. */ 20 | 21 | #include 22 | #include 23 | 24 | #include "sha1.h" 25 | 26 | void SHA1Transform(unsigned long state[5], unsigned char buffer[64]); 27 | 28 | #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) 29 | 30 | /* blk0() and blk() perform the initial expand. */ 31 | /* I got the idea of expanding during the round function from SSLeay */ 32 | #ifdef LITTLE_ENDIAN 33 | #define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \ 34 | |(rol(block->l[i],8)&0x00FF00FF)) 35 | #else 36 | #define blk0(i) block->l[i] 37 | #endif 38 | #define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \ 39 | ^block->l[(i+2)&15]^block->l[i&15],1)) 40 | 41 | /* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ 42 | #define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); 43 | #define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30); 44 | #define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); 45 | #define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); 46 | #define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); 47 | 48 | 49 | /* Hash a single 512-bit block. This is the core of the algorithm. */ 50 | 51 | void SHA1Transform(unsigned long state[5], unsigned char buffer[64]) 52 | { 53 | unsigned long a, b, c, d, e; 54 | typedef union { 55 | unsigned char c[64]; 56 | unsigned long l[16]; 57 | } CHAR64LONG16; 58 | CHAR64LONG16* block; 59 | #ifdef SHA1HANDSOFF 60 | static unsigned char workspace[64]; 61 | block = (CHAR64LONG16*)workspace; 62 | memcpy(block, buffer, 64); 63 | #else 64 | block = (CHAR64LONG16*)buffer; 65 | #endif 66 | /* Copy context->state[] to working vars */ 67 | a = state[0]; 68 | b = state[1]; 69 | c = state[2]; 70 | d = state[3]; 71 | e = state[4]; 72 | /* 4 rounds of 20 operations each. Loop unrolled. */ 73 | R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); 74 | R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); 75 | R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); 76 | R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); 77 | R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); 78 | R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); 79 | R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); 80 | R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); 81 | R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); 82 | R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); 83 | R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); 84 | R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); 85 | R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); 86 | R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); 87 | R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); 88 | R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); 89 | R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); 90 | R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); 91 | R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); 92 | R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); 93 | /* Add the working vars back into context.state[] */ 94 | state[0] += a; 95 | state[1] += b; 96 | state[2] += c; 97 | state[3] += d; 98 | state[4] += e; 99 | /* Wipe variables */ 100 | a = b = c = d = e = 0; 101 | 102 | (void)a; (void)b; (void)c; (void)d; (void)e; 103 | } 104 | 105 | 106 | /* SHA1Init - Initialize new context */ 107 | 108 | void SHA1Init(SHA1_CTX* context) 109 | { 110 | /* SHA1 initialization constants */ 111 | context->state[0] = 0x67452301; 112 | context->state[1] = 0xEFCDAB89; 113 | context->state[2] = 0x98BADCFE; 114 | context->state[3] = 0x10325476; 115 | context->state[4] = 0xC3D2E1F0; 116 | context->count[0] = context->count[1] = 0; 117 | } 118 | 119 | 120 | /* Run your data through this. */ 121 | 122 | void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int len) 123 | { 124 | unsigned int i, j; 125 | 126 | j = (context->count[0] >> 3) & 63; 127 | if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++; 128 | context->count[1] += (len >> 29); 129 | if ((j + len) > 63) { 130 | memcpy(&context->buffer[j], data, (i = 64-j)); 131 | SHA1Transform(context->state, context->buffer); 132 | for ( ; i + 63 < len; i += 64) { 133 | SHA1Transform(context->state, &data[i]); 134 | } 135 | j = 0; 136 | } 137 | else i = 0; 138 | memcpy(&context->buffer[j], &data[i], len - i); 139 | } 140 | 141 | 142 | /* Add padding and return the message digest. */ 143 | 144 | void SHA1Final(unsigned char digest[20], SHA1_CTX* context) 145 | { 146 | unsigned long i, j; 147 | unsigned char finalcount[8]; 148 | 149 | for (i = 0; i < 8; i++) { 150 | finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)] 151 | >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */ 152 | } 153 | SHA1Update(context, (unsigned char *)"\200", 1); 154 | while ((context->count[0] & 504) != 448) { 155 | SHA1Update(context, (unsigned char *)"\0", 1); 156 | } 157 | SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */ 158 | for (i = 0; i < 20; i++) { 159 | digest[i] = (unsigned char) 160 | ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); 161 | } 162 | /* Wipe variables */ 163 | i = j = 0; 164 | 165 | (void)i; (void)j; 166 | 167 | memset(context->buffer, 0, 64); 168 | memset(context->state, 0, 20); 169 | memset(context->count, 0, 8); 170 | memset(&finalcount, 0, 8); 171 | #ifdef SHA1HANDSOFF /* make SHA1Transform overwrite it's own static vars */ 172 | SHA1Transform(context->state, context->buffer); 173 | #endif 174 | } 175 | -------------------------------------------------------------------------------- /OAMutableURLRequest.m: -------------------------------------------------------------------------------- 1 | // 2 | // OAMutableURLRequest.m 3 | // OAuthConsumer 4 | // 5 | // Created by Jon Crosby on 10/19/07. 6 | // Copyright 2007 Kaboomerang LLC. All rights reserved. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in 16 | // all copies or substantial portions of the Software. 17 | // 18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | // THE SOFTWARE. 25 | 26 | 27 | #import "OAMutableURLRequest.h" 28 | 29 | 30 | @interface OAMutableURLRequest (Private) 31 | - (void)_generateTimestamp; 32 | - (void)_generateNonce; 33 | - (NSString *)_signatureBaseString; 34 | @end 35 | 36 | @implementation OAMutableURLRequest 37 | @synthesize signature, nonce; 38 | 39 | #pragma mark init 40 | 41 | - (id)initWithURL:(NSURL *)aUrl 42 | consumer:(OAConsumer *)aConsumer 43 | token:(OAToken *)aToken 44 | realm:(NSString *)aRealm 45 | signatureProvider:(id)aProvider { 46 | [super initWithURL:aUrl 47 | cachePolicy:NSURLRequestReloadIgnoringCacheData 48 | timeoutInterval:10.0]; 49 | 50 | consumer = aConsumer; 51 | 52 | // empty token for Unauthorized Request Token transaction 53 | if (aToken == nil) { 54 | token = [[OAToken alloc] init]; 55 | } else { 56 | token = [aToken retain]; 57 | } 58 | 59 | if (aRealm == nil) { 60 | realm = @""; 61 | } else { 62 | realm = [aRealm copy]; 63 | } 64 | 65 | // default to HMAC-SHA1 66 | if (aProvider == nil) { 67 | signatureProvider = [[OAHMAC_SHA1SignatureProvider alloc] init]; 68 | } else { 69 | signatureProvider = [aProvider retain]; 70 | } 71 | 72 | [self _generateTimestamp]; 73 | [self _generateNonce]; 74 | 75 | return self; 76 | } 77 | 78 | // Setting a timestamp and nonce to known 79 | // values can be helpful for testing 80 | - (id)initWithURL:(NSURL *)aUrl 81 | consumer:(OAConsumer *)aConsumer 82 | token:(OAToken *)aToken 83 | realm:(NSString *)aRealm 84 | signatureProvider:(id)aProvider 85 | nonce:(NSString *)aNonce 86 | timestamp:(NSString *)aTimestamp { 87 | [self initWithURL:aUrl 88 | consumer:aConsumer 89 | token:aToken 90 | realm:aRealm 91 | signatureProvider:aProvider]; 92 | 93 | nonce = [aNonce copy]; 94 | timestamp = [aTimestamp copy]; 95 | 96 | return self; 97 | } 98 | 99 | - (void)prepare { 100 | // sign 101 | // NSLog(@"Base string is: %@", [self _signatureBaseString]); 102 | signature = [signatureProvider signClearText:[self _signatureBaseString] 103 | withSecret:[NSString stringWithFormat:@"%@&%@", 104 | consumer.secret, 105 | token.secret ? token.secret : @""]]; 106 | 107 | // set OAuth headers 108 | NSMutableArray *chunks = [[NSMutableArray alloc] init]; 109 | [chunks addObject:[NSString stringWithFormat:@"realm=\"%@\"", [realm encodedURLParameterString]]]; 110 | [chunks addObject:[NSString stringWithFormat:@"oauth_consumer_key=\"%@\"", [consumer.key encodedURLParameterString]]]; 111 | 112 | NSDictionary *tokenParameters = [token parameters]; 113 | for (NSString *k in tokenParameters) { 114 | [chunks addObject:[NSString stringWithFormat:@"%@=\"%@\"", k, [[tokenParameters objectForKey:k] encodedURLParameterString]]]; 115 | } 116 | 117 | [chunks addObject:[NSString stringWithFormat:@"oauth_signature_method=\"%@\"", [[signatureProvider name] encodedURLParameterString]]]; 118 | [chunks addObject:[NSString stringWithFormat:@"oauth_signature=\"%@\"", [signature encodedURLParameterString]]]; 119 | [chunks addObject:[NSString stringWithFormat:@"oauth_timestamp=\"%@\"", timestamp]]; 120 | [chunks addObject:[NSString stringWithFormat:@"oauth_nonce=\"%@\"", nonce]]; 121 | [chunks addObject:@"oauth_version=\"1.0\""]; 122 | 123 | NSString *oauthHeader = [NSString stringWithFormat:@"OAuth %@", [chunks componentsJoinedByString:@", "]]; 124 | [chunks release]; 125 | 126 | [self setValue:oauthHeader forHTTPHeaderField:@"Authorization"]; 127 | } 128 | 129 | - (void)_generateTimestamp { 130 | [timestamp release]; 131 | timestamp = [[NSString alloc]initWithFormat:@"%d", time(NULL)]; 132 | } 133 | 134 | - (void)_generateNonce { 135 | CFUUIDRef theUUID = CFUUIDCreate(NULL); 136 | CFStringRef string = CFUUIDCreateString(NULL, theUUID); 137 | 138 | CFRelease(theUUID); 139 | if (nonce) { 140 | CFRelease(nonce); 141 | } 142 | 143 | nonce = (NSString *)string; 144 | } 145 | 146 | - (NSString *)_signatureBaseString { 147 | // OAuth Spec, Section 9.1.1 "Normalize Request Parameters" 148 | // build a sorted array of both request parameters and OAuth header parameters 149 | NSDictionary *tokenParameters = [token parameters]; 150 | // 6 being the number of OAuth params in the Signature Base String 151 | NSMutableArray *parameterPairs = [[NSMutableArray alloc] initWithCapacity:(5 + [[self parameters] count] + [tokenParameters count])]; 152 | 153 | [parameterPairs addObject:[[[[OARequestParameter alloc] initWithName:@"oauth_consumer_key" value:consumer.key] autorelease] URLEncodedNameValuePair]]; 154 | [parameterPairs addObject:[[[[OARequestParameter alloc] initWithName:@"oauth_signature_method" value:[signatureProvider name]] autorelease] URLEncodedNameValuePair]]; 155 | [parameterPairs addObject:[[[[OARequestParameter alloc] initWithName:@"oauth_timestamp" value:timestamp] autorelease] URLEncodedNameValuePair]]; 156 | [parameterPairs addObject:[[[[OARequestParameter alloc] initWithName:@"oauth_nonce" value:nonce] autorelease] URLEncodedNameValuePair]]; 157 | [parameterPairs addObject:[[[[OARequestParameter alloc] initWithName:@"oauth_version" value:@"1.0"] autorelease] URLEncodedNameValuePair]]; 158 | 159 | 160 | for(NSString *k in tokenParameters) { 161 | [parameterPairs addObject:[[OARequestParameter requestParameter:k value:[tokenParameters objectForKey:k]] URLEncodedNameValuePair]]; 162 | } 163 | 164 | if (![[self valueForHTTPHeaderField:@"Content-Type"] hasPrefix:@"multipart/form-data"]) { 165 | for (OARequestParameter *param in [self parameters]) { 166 | [parameterPairs addObject:[param URLEncodedNameValuePair]]; 167 | } 168 | } 169 | 170 | [parameterPairs sortUsingSelector:@selector(compare:)]; 171 | NSString *normalizedRequestParameters = [parameterPairs componentsJoinedByString:@"&"]; 172 | [parameterPairs release]; 173 | 174 | // NSLog(@"Normalized: %@", normalizedRequestParameters); 175 | // OAuth Spec, Section 9.1.2 "Concatenate Request Elements" 176 | return [NSString stringWithFormat:@"%@&%@&%@", 177 | [self HTTPMethod], 178 | [[[self URL] URLStringWithoutQuery] encodedURLParameterString], 179 | [normalizedRequestParameters encodedURLString]]; 180 | } 181 | 182 | - (void) dealloc 183 | { 184 | [token release]; 185 | [(NSObject*)signatureProvider release]; 186 | [timestamp release]; 187 | CFRelease(nonce); 188 | [super dealloc]; 189 | } 190 | 191 | @end 192 | -------------------------------------------------------------------------------- /Crypto/Base64Transcoder.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Base64Transcoder.c 3 | * Base64Test 4 | * 5 | * Created by Jonathan Wight on Tue Mar 18 2003. 6 | * Copyright (c) 2003 Toxic Software. All rights reserved. 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a copy 9 | * of this software and associated documentation files (the "Software"), to deal 10 | * in the Software without restriction, including without limitation the rights 11 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the Software is 13 | * furnished to do so, subject to the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included in 16 | * all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | * THE SOFTWARE. 25 | * 26 | */ 27 | 28 | #include "Base64Transcoder.h" 29 | 30 | #include 31 | #include 32 | 33 | const u_int8_t kBase64EncodeTable[64] = { 34 | /* 0 */ 'A', /* 1 */ 'B', /* 2 */ 'C', /* 3 */ 'D', 35 | /* 4 */ 'E', /* 5 */ 'F', /* 6 */ 'G', /* 7 */ 'H', 36 | /* 8 */ 'I', /* 9 */ 'J', /* 10 */ 'K', /* 11 */ 'L', 37 | /* 12 */ 'M', /* 13 */ 'N', /* 14 */ 'O', /* 15 */ 'P', 38 | /* 16 */ 'Q', /* 17 */ 'R', /* 18 */ 'S', /* 19 */ 'T', 39 | /* 20 */ 'U', /* 21 */ 'V', /* 22 */ 'W', /* 23 */ 'X', 40 | /* 24 */ 'Y', /* 25 */ 'Z', /* 26 */ 'a', /* 27 */ 'b', 41 | /* 28 */ 'c', /* 29 */ 'd', /* 30 */ 'e', /* 31 */ 'f', 42 | /* 32 */ 'g', /* 33 */ 'h', /* 34 */ 'i', /* 35 */ 'j', 43 | /* 36 */ 'k', /* 37 */ 'l', /* 38 */ 'm', /* 39 */ 'n', 44 | /* 40 */ 'o', /* 41 */ 'p', /* 42 */ 'q', /* 43 */ 'r', 45 | /* 44 */ 's', /* 45 */ 't', /* 46 */ 'u', /* 47 */ 'v', 46 | /* 48 */ 'w', /* 49 */ 'x', /* 50 */ 'y', /* 51 */ 'z', 47 | /* 52 */ '0', /* 53 */ '1', /* 54 */ '2', /* 55 */ '3', 48 | /* 56 */ '4', /* 57 */ '5', /* 58 */ '6', /* 59 */ '7', 49 | /* 60 */ '8', /* 61 */ '9', /* 62 */ '+', /* 63 */ '/' 50 | }; 51 | 52 | /* 53 | -1 = Base64 end of data marker. 54 | -2 = White space (tabs, cr, lf, space) 55 | -3 = Noise (all non whitespace, non-base64 characters) 56 | -4 = Dangerous noise 57 | -5 = Illegal noise (null byte) 58 | */ 59 | 60 | const int8_t kBase64DecodeTable[128] = { 61 | /* 0x00 */ -5, /* 0x01 */ -3, /* 0x02 */ -3, /* 0x03 */ -3, 62 | /* 0x04 */ -3, /* 0x05 */ -3, /* 0x06 */ -3, /* 0x07 */ -3, 63 | /* 0x08 */ -3, /* 0x09 */ -2, /* 0x0a */ -2, /* 0x0b */ -2, 64 | /* 0x0c */ -2, /* 0x0d */ -2, /* 0x0e */ -3, /* 0x0f */ -3, 65 | /* 0x10 */ -3, /* 0x11 */ -3, /* 0x12 */ -3, /* 0x13 */ -3, 66 | /* 0x14 */ -3, /* 0x15 */ -3, /* 0x16 */ -3, /* 0x17 */ -3, 67 | /* 0x18 */ -3, /* 0x19 */ -3, /* 0x1a */ -3, /* 0x1b */ -3, 68 | /* 0x1c */ -3, /* 0x1d */ -3, /* 0x1e */ -3, /* 0x1f */ -3, 69 | /* ' ' */ -2, /* '!' */ -3, /* '"' */ -3, /* '#' */ -3, 70 | /* '$' */ -3, /* '%' */ -3, /* '&' */ -3, /* ''' */ -3, 71 | /* '(' */ -3, /* ')' */ -3, /* '*' */ -3, /* '+' */ 62, 72 | /* ',' */ -3, /* '-' */ -3, /* '.' */ -3, /* '/' */ 63, 73 | /* '0' */ 52, /* '1' */ 53, /* '2' */ 54, /* '3' */ 55, 74 | /* '4' */ 56, /* '5' */ 57, /* '6' */ 58, /* '7' */ 59, 75 | /* '8' */ 60, /* '9' */ 61, /* ':' */ -3, /* ';' */ -3, 76 | /* '<' */ -3, /* '=' */ -1, /* '>' */ -3, /* '?' */ -3, 77 | /* '@' */ -3, /* 'A' */ 0, /* 'B' */ 1, /* 'C' */ 2, 78 | /* 'D' */ 3, /* 'E' */ 4, /* 'F' */ 5, /* 'G' */ 6, 79 | /* 'H' */ 7, /* 'I' */ 8, /* 'J' */ 9, /* 'K' */ 10, 80 | /* 'L' */ 11, /* 'M' */ 12, /* 'N' */ 13, /* 'O' */ 14, 81 | /* 'P' */ 15, /* 'Q' */ 16, /* 'R' */ 17, /* 'S' */ 18, 82 | /* 'T' */ 19, /* 'U' */ 20, /* 'V' */ 21, /* 'W' */ 22, 83 | /* 'X' */ 23, /* 'Y' */ 24, /* 'Z' */ 25, /* '[' */ -3, 84 | /* '\' */ -3, /* ']' */ -3, /* '^' */ -3, /* '_' */ -3, 85 | /* '`' */ -3, /* 'a' */ 26, /* 'b' */ 27, /* 'c' */ 28, 86 | /* 'd' */ 29, /* 'e' */ 30, /* 'f' */ 31, /* 'g' */ 32, 87 | /* 'h' */ 33, /* 'i' */ 34, /* 'j' */ 35, /* 'k' */ 36, 88 | /* 'l' */ 37, /* 'm' */ 38, /* 'n' */ 39, /* 'o' */ 40, 89 | /* 'p' */ 41, /* 'q' */ 42, /* 'r' */ 43, /* 's' */ 44, 90 | /* 't' */ 45, /* 'u' */ 46, /* 'v' */ 47, /* 'w' */ 48, 91 | /* 'x' */ 49, /* 'y' */ 50, /* 'z' */ 51, /* '{' */ -3, 92 | /* '|' */ -3, /* '}' */ -3, /* '~' */ -3, /* 0x7f */ -3 93 | }; 94 | 95 | const u_int8_t kBits_00000011 = 0x03; 96 | const u_int8_t kBits_00001111 = 0x0F; 97 | const u_int8_t kBits_00110000 = 0x30; 98 | const u_int8_t kBits_00111100 = 0x3C; 99 | const u_int8_t kBits_00111111 = 0x3F; 100 | const u_int8_t kBits_11000000 = 0xC0; 101 | const u_int8_t kBits_11110000 = 0xF0; 102 | const u_int8_t kBits_11111100 = 0xFC; 103 | 104 | size_t EstimateBas64EncodedDataSize(size_t inDataSize) 105 | { 106 | size_t theEncodedDataSize = (int)ceil(inDataSize / 3.0) * 4; 107 | theEncodedDataSize = theEncodedDataSize / 72 * 74 + theEncodedDataSize % 72; 108 | return(theEncodedDataSize); 109 | } 110 | 111 | size_t EstimateBas64DecodedDataSize(size_t inDataSize) 112 | { 113 | size_t theDecodedDataSize = (int)ceil(inDataSize / 4.0) * 3; 114 | //theDecodedDataSize = theDecodedDataSize / 72 * 74 + theDecodedDataSize % 72; 115 | return(theDecodedDataSize); 116 | } 117 | 118 | bool Base64EncodeData(const void *inInputData, size_t inInputDataSize, char *outOutputData, size_t *ioOutputDataSize) 119 | { 120 | size_t theEncodedDataSize = EstimateBas64EncodedDataSize(inInputDataSize); 121 | if (*ioOutputDataSize < theEncodedDataSize) 122 | return(false); 123 | *ioOutputDataSize = theEncodedDataSize; 124 | const u_int8_t *theInPtr = (const u_int8_t *)inInputData; 125 | u_int32_t theInIndex = 0, theOutIndex = 0; 126 | for (; theInIndex < (inInputDataSize / 3) * 3; theInIndex += 3) 127 | { 128 | outOutputData[theOutIndex++] = kBase64EncodeTable[(theInPtr[theInIndex] & kBits_11111100) >> 2]; 129 | outOutputData[theOutIndex++] = kBase64EncodeTable[(theInPtr[theInIndex] & kBits_00000011) << 4 | (theInPtr[theInIndex + 1] & kBits_11110000) >> 4]; 130 | outOutputData[theOutIndex++] = kBase64EncodeTable[(theInPtr[theInIndex + 1] & kBits_00001111) << 2 | (theInPtr[theInIndex + 2] & kBits_11000000) >> 6]; 131 | outOutputData[theOutIndex++] = kBase64EncodeTable[(theInPtr[theInIndex + 2] & kBits_00111111) >> 0]; 132 | if (theOutIndex % 74 == 72) 133 | { 134 | outOutputData[theOutIndex++] = '\r'; 135 | outOutputData[theOutIndex++] = '\n'; 136 | } 137 | } 138 | const size_t theRemainingBytes = inInputDataSize - theInIndex; 139 | if (theRemainingBytes == 1) 140 | { 141 | outOutputData[theOutIndex++] = kBase64EncodeTable[(theInPtr[theInIndex] & kBits_11111100) >> 2]; 142 | outOutputData[theOutIndex++] = kBase64EncodeTable[(theInPtr[theInIndex] & kBits_00000011) << 4 | (0 & kBits_11110000) >> 4]; 143 | outOutputData[theOutIndex++] = '='; 144 | outOutputData[theOutIndex++] = '='; 145 | if (theOutIndex % 74 == 72) 146 | { 147 | outOutputData[theOutIndex++] = '\r'; 148 | outOutputData[theOutIndex++] = '\n'; 149 | } 150 | } 151 | else if (theRemainingBytes == 2) 152 | { 153 | outOutputData[theOutIndex++] = kBase64EncodeTable[(theInPtr[theInIndex] & kBits_11111100) >> 2]; 154 | outOutputData[theOutIndex++] = kBase64EncodeTable[(theInPtr[theInIndex] & kBits_00000011) << 4 | (theInPtr[theInIndex + 1] & kBits_11110000) >> 4]; 155 | outOutputData[theOutIndex++] = kBase64EncodeTable[(theInPtr[theInIndex + 1] & kBits_00001111) << 2 | (0 & kBits_11000000) >> 6]; 156 | outOutputData[theOutIndex++] = '='; 157 | if (theOutIndex % 74 == 72) 158 | { 159 | outOutputData[theOutIndex++] = '\r'; 160 | outOutputData[theOutIndex++] = '\n'; 161 | } 162 | } 163 | (void)theOutIndex; // tell the static analyser we don't care that the last postincrement is never read 164 | return(true); 165 | 166 | // MODS THS - silence analyzer warnings about stored values never being read 167 | #pragma unused(theOutIndex) 168 | } 169 | 170 | bool Base64DecodeData(const void *inInputData, size_t inInputDataSize, void *ioOutputData, size_t *ioOutputDataSize) 171 | { 172 | memset(ioOutputData, '.', *ioOutputDataSize); 173 | 174 | size_t theDecodedDataSize = EstimateBas64DecodedDataSize(inInputDataSize); 175 | if (*ioOutputDataSize < theDecodedDataSize) 176 | return(false); 177 | *ioOutputDataSize = 0; 178 | const u_int8_t *theInPtr = (const u_int8_t *)inInputData; 179 | u_int8_t *theOutPtr = (u_int8_t *)ioOutputData; 180 | size_t theInIndex = 0, theOutIndex = 0; 181 | u_int8_t theOutputOctet = 0; 182 | size_t theSequence = 0; 183 | for (; theInIndex < inInputDataSize; ) 184 | { 185 | int8_t theSextet = 0; 186 | 187 | int8_t theCurrentInputOctet = theInPtr[theInIndex]; 188 | theSextet = kBase64DecodeTable[theCurrentInputOctet]; 189 | if (theSextet == -1) 190 | break; 191 | while (theSextet == -2) 192 | { 193 | theCurrentInputOctet = theInPtr[++theInIndex]; 194 | theSextet = kBase64DecodeTable[theCurrentInputOctet]; 195 | } 196 | while (theSextet == -3) 197 | { 198 | theCurrentInputOctet = theInPtr[++theInIndex]; 199 | theSextet = kBase64DecodeTable[theCurrentInputOctet]; 200 | } 201 | if (theSequence == 0) 202 | { 203 | theOutputOctet = (theSextet >= 0 ? theSextet : 0) << 2 & kBits_11111100; 204 | } 205 | else if (theSequence == 1) 206 | { 207 | theOutputOctet |= (theSextet >- 0 ? theSextet : 0) >> 4 & kBits_00000011; 208 | theOutPtr[theOutIndex++] = theOutputOctet; 209 | } 210 | else if (theSequence == 2) 211 | { 212 | theOutputOctet = (theSextet >= 0 ? theSextet : 0) << 4 & kBits_11110000; 213 | } 214 | else if (theSequence == 3) 215 | { 216 | theOutputOctet |= (theSextet >= 0 ? theSextet : 0) >> 2 & kBits_00001111; 217 | theOutPtr[theOutIndex++] = theOutputOctet; 218 | } 219 | else if (theSequence == 4) 220 | { 221 | theOutputOctet = (theSextet >= 0 ? theSextet : 0) << 6 & kBits_11000000; 222 | } 223 | else if (theSequence == 5) 224 | { 225 | theOutputOctet |= (theSextet >= 0 ? theSextet : 0) >> 0 & kBits_00111111; 226 | theOutPtr[theOutIndex++] = theOutputOctet; 227 | } 228 | theSequence = (theSequence + 1) % 6; 229 | if (theSequence != 2 && theSequence != 4) 230 | theInIndex++; 231 | } 232 | *ioOutputDataSize = theOutIndex; 233 | return(true); 234 | } 235 | -------------------------------------------------------------------------------- /OAToken.m: -------------------------------------------------------------------------------- 1 | // 2 | // OAToken.m 3 | // OAuthConsumer 4 | // 5 | // Created by Jon Crosby on 10/19/07. 6 | // Copyright 2007 Kaboomerang LLC. All rights reserved. 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in 16 | // all copies or substantial portions of the Software. 17 | // 18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | // THE SOFTWARE. 25 | 26 | 27 | #import "NSString+URLEncoding.h" 28 | #import "OAToken.h" 29 | 30 | @interface OAToken (Private) 31 | 32 | + (NSString *)settingsKey:(const NSString *)name provider:(const NSString *)provider prefix:(const NSString *)prefix; 33 | + (id)loadSetting:(const NSString *)name provider:(const NSString *)provider prefix:(const NSString *)prefix; 34 | + (void)saveSetting:(NSString *)name object:(id)object provider:(const NSString *)provider prefix:(const NSString *)prefix; 35 | + (NSNumber *)durationWithString:(NSString *)aDuration; 36 | + (NSMutableDictionary *)attributesWithString:(NSString *)theAttributes; 37 | 38 | @end 39 | 40 | @implementation OAToken 41 | 42 | @synthesize key, secret, session, duration, forRenewal, verifier; 43 | 44 | #pragma mark init 45 | 46 | - (id)init { 47 | return [self initWithKey:nil secret:nil]; 48 | } 49 | 50 | - (id)initWithKey:(NSString *)aKey secret:(NSString *)aSecret { 51 | return [self initWithKey:aKey secret:aSecret verifier:nil session:nil duration:nil 52 | attributes:nil created:nil renewable:NO]; 53 | } 54 | 55 | - (id)initWithKey:(NSString *)aKey secret:(NSString *)aSecret verifier:(NSString *)aVerifier session:(NSString *)aSession 56 | duration:(NSNumber *)aDuration attributes:(NSDictionary *)theAttributes created:(NSDate *)creation 57 | renewable:(BOOL)renew { 58 | [super init]; 59 | self.key = aKey; 60 | self.secret = aSecret; 61 | self.verifier = aVerifier; 62 | self.session = aSession; 63 | self.duration = aDuration; 64 | self.attributes = theAttributes; 65 | created = [creation retain]; 66 | renewable = renew; 67 | forRenewal = NO; 68 | 69 | return self; 70 | } 71 | 72 | - (id)initWithHTTPResponseBody:(const NSString *)body { 73 | NSString *aKey = nil; 74 | NSString *aSecret = nil; 75 | NSString *aVerifier = nil; 76 | NSString *aSession = nil; 77 | NSNumber *aDuration = nil; 78 | NSDate *creationDate = nil; 79 | NSDictionary *attrs = nil; 80 | BOOL renew = NO; 81 | NSArray *pairs = [body componentsSeparatedByString:@"&"]; 82 | 83 | for (NSString *pair in pairs) { 84 | NSArray *elements = [pair componentsSeparatedByString:@"="]; 85 | if ([[elements objectAtIndex:0] isEqualToString:@"oauth_token"]) { 86 | aKey = [elements objectAtIndex:1]; 87 | } else if ([[elements objectAtIndex:0] isEqualToString:@"oauth_token_secret"]) { 88 | aSecret = [elements objectAtIndex:1]; 89 | } else if ([[elements objectAtIndex:0] isEqualToString:@"oauth_verifier"]) { 90 | aVerifier = [elements objectAtIndex:1]; 91 | } else if ([[elements objectAtIndex:0] isEqualToString:@"oauth_session_handle"]) { 92 | aSession = [elements objectAtIndex:1]; 93 | } else if ([[elements objectAtIndex:0] isEqualToString:@"oauth_token_duration"]) { 94 | aDuration = [[self class] durationWithString:[elements objectAtIndex:1]]; 95 | creationDate = [NSDate date]; 96 | } else if ([[elements objectAtIndex:0] isEqualToString:@"oauth_token_attributes"]) { 97 | attrs = [[self class] attributesWithString:[[elements objectAtIndex:1] decodedURLString]]; 98 | } else if ([[elements objectAtIndex:0] isEqualToString:@"oauth_token_renewable"]) { 99 | NSString *lowerCase = [[elements objectAtIndex:1] lowercaseString]; 100 | if ([lowerCase isEqualToString:@"true"] || [lowerCase isEqualToString:@"t"]) { 101 | renew = YES; 102 | } 103 | } 104 | } 105 | 106 | return [self initWithKey:aKey secret:aSecret verifier:aVerifier session:aSession duration:aDuration 107 | attributes:attrs created:creationDate renewable:renew]; 108 | } 109 | 110 | - (id)initWithUserDefaultsUsingServiceProviderName:(const NSString *)provider prefix:(const NSString *)prefix { 111 | [super init]; 112 | self.key = [OAToken loadSetting:@"key" provider:provider prefix:prefix]; 113 | self.secret = [OAToken loadSetting:@"secret" provider:provider prefix:prefix]; 114 | self.verifier = [OAToken loadSetting:@"verifier" provider:provider prefix:prefix]; 115 | self.session = [OAToken loadSetting:@"session" provider:provider prefix:prefix]; 116 | self.duration = [OAToken loadSetting:@"duration" provider:provider prefix:prefix]; 117 | self.attributes = [OAToken loadSetting:@"attributes" provider:provider prefix:prefix]; 118 | created = [OAToken loadSetting:@"created" provider:provider prefix:prefix]; 119 | renewable = [[OAToken loadSetting:@"renewable" provider:provider prefix:prefix] boolValue]; 120 | 121 | if (![self isValid]) { 122 | [self autorelease]; 123 | return nil; 124 | } 125 | 126 | return self; 127 | } 128 | 129 | #pragma mark dealloc 130 | 131 | - (void)dealloc { 132 | self.key = nil; 133 | self.secret = nil; 134 | self.verifier = nil; 135 | self.duration = nil; 136 | self.attributes = nil; 137 | [super dealloc]; 138 | } 139 | 140 | #pragma mark settings 141 | 142 | - (BOOL)isValid { 143 | return (key != nil && ![key isEqualToString:@""] && secret != nil && ![secret isEqualToString:@""]); 144 | } 145 | 146 | - (int)storeInUserDefaultsWithServiceProviderName:(const NSString *)provider prefix:(const NSString *)prefix { 147 | [OAToken saveSetting:@"key" object:key provider:provider prefix:prefix]; 148 | [OAToken saveSetting:@"secret" object:secret provider:provider prefix:prefix]; 149 | [OAToken saveSetting:@"verifier" object:verifier provider:provider prefix:prefix]; 150 | [OAToken saveSetting:@"created" object:created provider:provider prefix:prefix]; 151 | [OAToken saveSetting:@"duration" object:duration provider:provider prefix:prefix]; 152 | [OAToken saveSetting:@"session" object:session provider:provider prefix:prefix]; 153 | [OAToken saveSetting:@"attributes" object:attributes provider:provider prefix:prefix]; 154 | [OAToken saveSetting:@"renewable" object:renewable ? @"t" : @"f" provider:provider prefix:prefix]; 155 | 156 | [[NSUserDefaults standardUserDefaults] synchronize]; 157 | return(0); 158 | } 159 | 160 | #pragma mark duration 161 | 162 | - (void)setDurationWithString:(NSString *)aDuration { 163 | self.duration = [[self class] durationWithString:aDuration]; 164 | } 165 | 166 | - (BOOL)hasExpired 167 | { 168 | return created && [created timeIntervalSinceNow] > [duration intValue]; 169 | } 170 | 171 | - (BOOL)isRenewable 172 | { 173 | return session && renewable && created && [created timeIntervalSinceNow] < (2 * [duration intValue]); 174 | } 175 | 176 | 177 | #pragma mark attributes 178 | 179 | - (void)setAttribute:(const NSString *)aKey value:(const NSString *)aAttribute { 180 | if (!attributes) { 181 | attributes = [[NSMutableDictionary alloc] init]; 182 | } 183 | [attributes setObject: aAttribute forKey: aKey]; 184 | } 185 | 186 | - (NSDictionary *)attributes { 187 | return [[attributes copy] autorelease]; 188 | } 189 | 190 | - (void)setAttributes:(NSDictionary *)theAttributes { 191 | [attributes release]; 192 | 193 | if (theAttributes) { 194 | attributes = [[NSMutableDictionary alloc] initWithDictionary:theAttributes]; 195 | }else { 196 | attributes = nil; 197 | } 198 | } 199 | 200 | - (BOOL)hasAttributes { 201 | return (attributes && [attributes count] > 0); 202 | } 203 | 204 | - (NSString *)attributeString { 205 | if (![self hasAttributes]) { 206 | return @""; 207 | } 208 | 209 | NSMutableArray *chunks = [[NSMutableArray alloc] init]; 210 | for(NSString *aKey in self->attributes) { 211 | [chunks addObject:[NSString stringWithFormat:@"%@:%@", aKey, [attributes objectForKey:aKey]]]; 212 | } 213 | NSString *attrs = [chunks componentsJoinedByString:@";"]; 214 | [chunks release]; 215 | return attrs; 216 | } 217 | 218 | - (NSString *)attribute:(NSString *)aKey 219 | { 220 | return [attributes objectForKey:aKey]; 221 | } 222 | 223 | - (void)setAttributesWithString:(NSString *)theAttributes 224 | { 225 | self.attributes = [[self class] attributesWithString:theAttributes]; 226 | } 227 | 228 | - (NSDictionary *)parameters 229 | { 230 | NSMutableDictionary *params = [[[NSMutableDictionary alloc] init] autorelease]; 231 | 232 | if (key) { 233 | [params setObject:key forKey:@"oauth_token"]; 234 | if ([self isForRenewal]) { 235 | [params setObject:session forKey:@"oauth_session_handle"]; 236 | } 237 | } else { 238 | if (duration) { 239 | [params setObject:[duration stringValue] forKey: @"oauth_token_duration"]; 240 | } 241 | if ([attributes count]) { 242 | [params setObject:[self attributeString] forKey:@"oauth_token_attributes"]; 243 | } 244 | } 245 | return params; 246 | } 247 | 248 | #pragma mark comparisions 249 | 250 | - (BOOL)isEqual:(id)object { 251 | if([object isKindOfClass:[self class]]) { 252 | return [self isEqualToToken:(OAToken *)object]; 253 | } 254 | return NO; 255 | } 256 | 257 | - (BOOL)isEqualToToken:(OAToken *)aToken { 258 | /* Since ScalableOAuth determines that the token may be 259 | renewed using the same key and secret, we must also 260 | check the creation date */ 261 | if ([self.key isEqualToString:aToken.key] && 262 | [self.secret isEqualToString:aToken.secret]) { 263 | /* May be nil */ 264 | if (created == aToken->created || [created isEqualToDate:aToken->created]) { 265 | return YES; 266 | } 267 | } 268 | 269 | return NO; 270 | } 271 | 272 | #pragma mark class_functions 273 | 274 | + (NSString *)settingsKey:(NSString *)name provider:(NSString *)provider prefix:(NSString *)prefix { 275 | return [NSString stringWithFormat:@"OAUTH_%@_%@_%@", provider, prefix, [name uppercaseString]]; 276 | } 277 | 278 | + (id)loadSetting:(NSString *)name provider:(NSString *)provider prefix:(NSString *)prefix { 279 | return [[NSUserDefaults standardUserDefaults] objectForKey:[self settingsKey:name 280 | provider:provider 281 | prefix:prefix]]; 282 | } 283 | 284 | + (void)saveSetting:(NSString *)name object:(id)object provider:(NSString *)provider prefix:(NSString *)prefix { 285 | [[NSUserDefaults standardUserDefaults] setObject:object forKey:[self settingsKey:name 286 | provider:provider 287 | prefix:prefix]]; 288 | } 289 | 290 | + (void)removeFromUserDefaultsWithServiceProviderName:(NSString *)provider prefix:(NSString *)prefix { 291 | NSArray *keys = [NSArray arrayWithObjects:@"key", @"secret", @"created", @"duration", @"session", @"attributes", @"renewable", nil]; 292 | for(NSString *name in keys) { 293 | [[NSUserDefaults standardUserDefaults] removeObjectForKey:[OAToken settingsKey:name provider:provider prefix:prefix]]; 294 | } 295 | } 296 | 297 | + (NSNumber *)durationWithString:(NSString *)aDuration { 298 | NSUInteger length = [aDuration length]; 299 | unichar c = toupper([aDuration characterAtIndex:length - 1]); 300 | int mult; 301 | if (c >= '0' && c <= '9') { 302 | return [NSNumber numberWithInt:[aDuration intValue]]; 303 | } 304 | if (c == 'S') { 305 | mult = 1; 306 | } else if (c == 'H') { 307 | mult = 60 * 60; 308 | } else if (c == 'D') { 309 | mult = 60 * 60 * 24; 310 | } else if (c == 'W') { 311 | mult = 60 * 60 * 24 * 7; 312 | } else if (c == 'M') { 313 | mult = 60 * 60 * 24 * 30; 314 | } else if (c == 'Y') { 315 | mult = 60 * 60 * 365; 316 | } else { 317 | mult = 1; 318 | } 319 | 320 | return [NSNumber numberWithInt: mult * [[aDuration substringToIndex:length - 1] intValue]]; 321 | } 322 | 323 | + (NSDictionary *)attributesWithString:(NSString *)theAttributes { 324 | NSArray *attrs = [theAttributes componentsSeparatedByString:@";"]; 325 | NSMutableDictionary *dct = [[NSMutableDictionary alloc] init]; 326 | for (NSString *pair in attrs) { 327 | NSArray *elements = [pair componentsSeparatedByString:@":"]; 328 | [dct setObject:[elements objectAtIndex:1] forKey:[elements objectAtIndex:0]]; 329 | } 330 | return [dct autorelease]; 331 | } 332 | 333 | #pragma mark description 334 | 335 | - (NSString *)description { 336 | return [NSString stringWithFormat:@"Key \"%@\" Secret:\"%@\"", key, secret]; 337 | } 338 | 339 | @end 340 | -------------------------------------------------------------------------------- /OATokenManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // OATokenManager.m 3 | // OAuthConsumer 4 | // 5 | // Created by Alberto García Hierro on 01/09/08. 6 | // Copyright 2008 Alberto García Hierro. All rights reserved. 7 | // bynotes.com 8 | 9 | #import "OAConsumer.h" 10 | #import "OAToken.h" 11 | #import "OAProblem.h" 12 | #import "OACall.h" 13 | #import "OATokenManager.h" 14 | 15 | #if TARGET_OS_IPHONE 16 | #import 17 | #else 18 | #import 19 | #endif 20 | 21 | @interface OATokenManager (Private) 22 | 23 | - (void)callProblem:(OACall *)call problem:(OAProblem *)problem; 24 | - (void)callError:(OACall *)call error:(NSError *)error; 25 | - (void)callFinished:(OACall *)call body:(NSString *)body; 26 | 27 | - (void)dispatch; 28 | - (void)performCall:(OACall *)aCall; 29 | 30 | - (void)requestToken; 31 | - (void)requestTokenReceived; 32 | - (void)exchangeToken; 33 | - (void)renewToken; 34 | - (void)accessTokenReceived; 35 | - (void)setAccessToken:(OAToken *)token; 36 | - (void)deleteSavedRequestToken; 37 | 38 | - (OACall *)queue; 39 | - (void)enqueue:(OACall *)call selector:(SEL)selector; 40 | - (void)dequeue:(OACall *)call; 41 | - (SEL)getSelector:(OACall *)call; 42 | 43 | @end 44 | 45 | @implementation OATokenManager 46 | 47 | - (id)init { 48 | return [self initWithConsumer:nil 49 | token:nil 50 | oauthBase:nil 51 | realm:nil 52 | callback:nil 53 | delegate:nil]; 54 | } 55 | 56 | - (id)initWithConsumer:(OAConsumer *)aConsumer token:(OAToken *)aToken oauthBase:(const NSString *)base 57 | realm:(const NSString *)aRealm callback:(const NSString *)aCallback 58 | delegate:(NSObject *)aDelegate { 59 | 60 | [super init]; 61 | consumer = [aConsumer retain]; 62 | acToken = nil; 63 | reqToken = nil; 64 | initialToken = [aToken retain]; 65 | authorizedTokenKey = nil; 66 | oauthBase = [base copy]; 67 | realm = [aRealm copy]; 68 | callback = [aCallback copy]; 69 | delegate = aDelegate; 70 | calls = [[NSMutableArray alloc] init]; 71 | selectors = [[NSMutableArray alloc] init]; 72 | delegates = [[NSMutableDictionary alloc] init]; 73 | isDispatching = NO; 74 | 75 | return self; 76 | } 77 | 78 | - (void)dealloc { 79 | [consumer release]; 80 | [acToken release]; 81 | [reqToken release]; 82 | [initialToken release]; 83 | [authorizedTokenKey release]; 84 | [oauthBase release]; 85 | [realm release]; 86 | [callback release]; 87 | [calls release]; 88 | [selectors release]; 89 | [delegates release]; 90 | [super dealloc]; 91 | } 92 | 93 | // The application got a new authorized 94 | // request token and is notifying us 95 | - (void)authorizedToken:(const NSString *)aKey 96 | { 97 | if (reqToken && [aKey isEqualToString:reqToken.key]) { 98 | [self exchangeToken]; 99 | } else { 100 | [authorizedTokenKey release]; 101 | authorizedTokenKey = [aKey retain]; 102 | } 103 | } 104 | 105 | 106 | // Private functions 107 | 108 | // Deal with problems and errors in calls 109 | 110 | - (void)call:(OACall *)call failedWithProblem:(OAProblem *)problem 111 | { 112 | /* Always clear the saved request token, just in case */ 113 | [self deleteSavedRequestToken]; 114 | 115 | if ([problem isEqualToProblem:[OAProblem TokenExpired]]) { 116 | /* renewToken checks if it's renewable */ 117 | [self renewToken]; 118 | } else if ([problem isEqualToProblem:[OAProblem TokenNotRenewable]] || 119 | [problem isEqualToProblem:[OAProblem TokenRejected]]) { 120 | /* This token may have been revoked by the user, get a new one 121 | after removing the stored requestToken, since the problem may be in 122 | it */ 123 | [self setAccessToken:nil]; 124 | [self requestToken]; 125 | } else if ([problem isEqualToProblem:[OAProblem NonceUsed]]) { 126 | /* Just repeat this request */ 127 | [self performCall:call]; 128 | } else { 129 | /* Non-recoverable error, tell the delegate and dequeue the call 130 | if appropiate */ 131 | if([delegate tokenManager:self failedCall:call withProblem:problem]) { 132 | [self dequeue:call]; 133 | } 134 | @synchronized(self) { 135 | isDispatching = NO; 136 | } 137 | } 138 | } 139 | 140 | - (void)call:(OACall *)call failedWithError:(NSError *)error 141 | { 142 | if([delegate tokenManager:self failedCall:call withError:error]) { 143 | [self dequeue:call]; 144 | } 145 | @synchronized(self) { 146 | isDispatching = NO; 147 | } 148 | } 149 | 150 | // When a call finish, notify the delegate 151 | - (void)callFinished:(OACall *)call body:(NSString *)body 152 | { 153 | SEL selector = [self getSelector:call]; 154 | id deleg = [delegates objectForKey:[NSString stringWithFormat:@"%p", call]]; 155 | if (deleg) { 156 | [deleg performSelector:selector withObject:body]; 157 | [delegates removeObjectForKey:call]; 158 | } else { 159 | [delegate performSelector:selector withObject:body]; 160 | } 161 | @synchronized(self) { 162 | isDispatching = NO; 163 | } 164 | [self dequeue:call]; 165 | [self dispatch]; 166 | } 167 | 168 | - (OACall *)queue { 169 | id obj = nil; 170 | @synchronized(calls) { 171 | if ([calls count]) { 172 | obj = [calls objectAtIndex:0]; 173 | } 174 | } 175 | return obj; 176 | } 177 | 178 | - (void)enqueue:(OACall *)call selector:(SEL)selector { 179 | NSUInteger idx = [calls indexOfObject:call]; 180 | if (idx == NSNotFound) { 181 | @synchronized(calls) { 182 | [calls addObject:call]; 183 | [call release]; 184 | [selectors addObject:NSStringFromSelector(selector)]; 185 | } 186 | } 187 | } 188 | 189 | - (void)dequeue:(OACall *)call { 190 | NSUInteger idx = [calls indexOfObject:call]; 191 | if (idx != NSNotFound) { 192 | @synchronized(calls) { 193 | [calls removeObjectAtIndex:idx]; 194 | [selectors removeObjectAtIndex:idx]; 195 | } 196 | } 197 | } 198 | 199 | - (SEL)getSelector:(OACall *)call 200 | { 201 | NSUInteger idx = [calls indexOfObject:call]; 202 | if (idx != NSNotFound) { 203 | return NSSelectorFromString([selectors objectAtIndex:idx]); 204 | } 205 | return 0; 206 | } 207 | 208 | // Token management functions 209 | 210 | // Requesting a new token 211 | 212 | // Gets a new token and opens the default 213 | // browser for authorizing it. The application 214 | // is expected to call authorizedToken when it 215 | // gets the authorized token back 216 | 217 | - (void)requestToken 218 | { 219 | /* Try to load an access token from settings */ 220 | OAToken *atoken = [[[OAToken alloc] initWithUserDefaultsUsingServiceProviderName:oauthBase prefix:[@"access:" stringByAppendingString:realm]] autorelease]; 221 | if (atoken && [atoken isValid]) { 222 | [self setAccessToken:atoken]; 223 | return; 224 | } 225 | /* Try to load a stored requestToken from 226 | settings (useful for iPhone) */ 227 | OAToken *token = [[[OAToken alloc] initWithUserDefaultsUsingServiceProviderName:oauthBase prefix:[@"request:" stringByAppendingString:realm]] autorelease]; 228 | /* iPhone specific, the manager must have got the authorized token before reaching this point */ 229 | NSLog(@"request token in settings %@", token); 230 | if (token && token.key && [authorizedTokenKey isEqualToString:token.key]) { 231 | reqToken = [token retain]; 232 | [self exchangeToken]; 233 | return; 234 | } 235 | if ([delegate respondsToSelector:@selector(tokenManagerNeedsToken:)]) { 236 | if (![delegate tokenManagerNeedsToken:self]) { 237 | return; 238 | } 239 | } 240 | OACall *call = [[OACall alloc] initWithURL:[NSURL URLWithString:[oauthBase stringByAppendingString:@"request_token"]] method:@"POST"]; 241 | [call perform:consumer 242 | token:initialToken 243 | realm:realm 244 | delegate:self 245 | didFinish:@selector(requestTokenReceived:body:)]; 246 | 247 | } 248 | 249 | - (void)requestTokenReceived:(OACall *)call body:(NSString *)body 250 | { 251 | /* XXX: Check if token != nil */ 252 | NSLog(@"Received request token %@", body); 253 | OAToken *token = [[[OAToken alloc] initWithHTTPResponseBody:body] autorelease]; 254 | if (token) { 255 | [reqToken release]; 256 | reqToken = [token retain]; 257 | 258 | [reqToken storeInUserDefaultsWithServiceProviderName:oauthBase prefix:[@"request:" stringByAppendingString:realm]]; 259 | /* Save the token in case we exit and start again 260 | before the token is authorized (useful for iPhone) */ 261 | NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@authorize?oauth_token=%@&oauth_callback=%@", 262 | oauthBase, token.key, callback]]; 263 | 264 | #if TARGET_OS_IPHONE 265 | [[UIApplication sharedApplication] openURL:url]; 266 | #else 267 | [[NSWorkspace sharedWorkspace] openURL:url]; 268 | #endif 269 | 270 | } 271 | [call release]; 272 | } 273 | 274 | // Exchaing a request token for an access token 275 | 276 | // Exchanges the current authorized 277 | // request token for an access token 278 | - (void)exchangeToken 279 | { 280 | if (!reqToken) { 281 | [self requestToken]; 282 | return; 283 | } 284 | NSURL *url = [NSURL URLWithString:[oauthBase stringByAppendingString:@"access_token"]]; 285 | OACall *call = [[OACall alloc] initWithURL:url method:@"POST"]; 286 | [call perform:consumer 287 | token:reqToken 288 | realm:realm 289 | delegate:self 290 | didFinish:@selector(accessTokenReceived:body:)]; 291 | } 292 | 293 | - (void)accessTokenReceived:(OACall *)call body:(NSString *)body 294 | { 295 | OAToken *token = [[OAToken alloc] initWithHTTPResponseBody:body]; 296 | [self setAccessToken:token]; 297 | } 298 | 299 | - (void)renewToken { 300 | NSLog(@"Renewing token"); 301 | if (!acToken || ![acToken isRenewable]) { 302 | [self requestToken]; 303 | return; 304 | } 305 | acToken.forRenewal = YES; 306 | NSURL *url = [NSURL URLWithString:[oauthBase stringByAppendingString:@"access_token"]]; 307 | OACall *call = [[OACall alloc] initWithURL:url method:@"POST"]; 308 | [call perform:consumer 309 | token:acToken 310 | realm:realm 311 | delegate:self 312 | didFinish:@selector(accessTokenReceived:body:)]; 313 | } 314 | 315 | - (void)setAccessToken:(OAToken *)token { 316 | /* Remove the stored requestToken which generated 317 | this access token */ 318 | [self deleteSavedRequestToken]; 319 | if (token) { 320 | [acToken release]; 321 | acToken = [token retain]; 322 | [acToken storeInUserDefaultsWithServiceProviderName:oauthBase prefix:[@"access:" stringByAppendingString:realm]]; 323 | @synchronized(self) { 324 | isDispatching = NO; 325 | } 326 | [self dispatch]; 327 | } else { 328 | /* Clear the in-memory and saved access tokens */ 329 | [acToken release]; 330 | acToken = nil; 331 | [OAToken removeFromUserDefaultsWithServiceProviderName:oauthBase prefix:[@"access:" stringByAppendingString:realm]]; 332 | } 333 | } 334 | 335 | - (void)deleteSavedRequestToken { 336 | [OAToken removeFromUserDefaultsWithServiceProviderName:oauthBase prefix:[@"request:" stringByAppendingString:realm]]; 337 | [reqToken release]; 338 | reqToken = nil; 339 | } 340 | 341 | - (void)performCall:(OACall *)aCall { 342 | NSLog(@"Performing call"); 343 | [aCall perform:consumer 344 | token:acToken 345 | realm:realm 346 | delegate:self 347 | didFinish:@selector(callFinished:body:)]; 348 | } 349 | 350 | - (void)dispatch { 351 | OACall *call = [self queue]; 352 | if (!call) { 353 | return; 354 | } 355 | @synchronized(self) { 356 | if (isDispatching) { 357 | return; 358 | } 359 | isDispatching = YES; 360 | } 361 | NSLog(@"Started dispatching"); 362 | if(acToken) { 363 | [self performCall:call]; 364 | } else if(reqToken) { 365 | [self exchangeToken]; 366 | } else { 367 | [self requestToken]; 368 | } 369 | } 370 | 371 | - (void)fetchData:(NSString *)aURL method:(NSString *)aMethod parameters:(NSArray *)theParameters 372 | files:(NSDictionary *)theFiles finished:(SEL)didFinish delegate:(NSObject*)aDelegate { 373 | 374 | OACall *call = [[OACall alloc] initWithURL:[NSURL URLWithString:aURL] 375 | method:aMethod 376 | parameters:theParameters 377 | files:theFiles]; 378 | NSLog(@"Received request for: %@", aURL); 379 | [self enqueue:call selector:didFinish]; 380 | if (aDelegate) { 381 | [delegates setObject:aDelegate forKey:[NSString stringWithFormat:@"%p", call]]; 382 | } 383 | [self dispatch]; 384 | } 385 | 386 | - (void)fetchData:(NSString *)aURL method:(NSString *)aMethod parameters:(NSArray *)theParameters 387 | files:(NSDictionary *)theFiles finished:(SEL)didFinish { 388 | 389 | [self fetchData:aURL method:aMethod parameters:theParameters files:theFiles 390 | finished:didFinish delegate:nil]; 391 | } 392 | 393 | 394 | - (void)fetchData:(NSString *)aURL method:(NSString *)aMethod parameters:(NSArray *)theParameters 395 | finished:(SEL)didFinish { 396 | 397 | [self fetchData:aURL method:aMethod parameters:theParameters files:nil finished:didFinish]; 398 | } 399 | 400 | - (void)fetchData:(NSString *)aURL parameters:(NSArray *)theParameters files:(NSDictionary *)theFiles 401 | finished:(SEL)didFinish { 402 | 403 | [self fetchData:aURL method:@"POST" parameters:theParameters files:theFiles finished:didFinish]; 404 | } 405 | 406 | - (void)fetchData:(NSString *)aURL finished:(SEL)didFinish { 407 | [self fetchData:aURL method:nil parameters:nil files:nil finished:didFinish]; 408 | } 409 | 410 | 411 | @end 412 | -------------------------------------------------------------------------------- /OAuthConsumer.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 45; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 56E3CC6B12DD138800D58587 /* NSMutableURLRequest+Parameters.h in Headers */ = {isa = PBXBuildFile; fileRef = 56E3CC4612DD138800D58587 /* NSMutableURLRequest+Parameters.h */; settings = {ATTRIBUTES = (Public, ); }; }; 11 | 56E3CC6C12DD138800D58587 /* NSMutableURLRequest+Parameters.m in Sources */ = {isa = PBXBuildFile; fileRef = 56E3CC4712DD138800D58587 /* NSMutableURLRequest+Parameters.m */; }; 12 | 56E3CC6D12DD138800D58587 /* NSString+URLEncoding.h in Headers */ = {isa = PBXBuildFile; fileRef = 56E3CC4812DD138800D58587 /* NSString+URLEncoding.h */; settings = {ATTRIBUTES = (Public, ); }; }; 13 | 56E3CC6E12DD138800D58587 /* NSString+URLEncoding.m in Sources */ = {isa = PBXBuildFile; fileRef = 56E3CC4912DD138800D58587 /* NSString+URLEncoding.m */; }; 14 | 56E3CC6F12DD138800D58587 /* NSURL+Base.h in Headers */ = {isa = PBXBuildFile; fileRef = 56E3CC4A12DD138800D58587 /* NSURL+Base.h */; settings = {ATTRIBUTES = (Public, ); }; }; 15 | 56E3CC7012DD138800D58587 /* NSURL+Base.m in Sources */ = {isa = PBXBuildFile; fileRef = 56E3CC4B12DD138800D58587 /* NSURL+Base.m */; }; 16 | 56E3CC7112DD138800D58587 /* Base64Transcoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 56E3CC4D12DD138800D58587 /* Base64Transcoder.c */; }; 17 | 56E3CC7212DD138800D58587 /* Base64Transcoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 56E3CC4E12DD138800D58587 /* Base64Transcoder.h */; }; 18 | 56E3CC7312DD138800D58587 /* hmac.c in Sources */ = {isa = PBXBuildFile; fileRef = 56E3CC4F12DD138800D58587 /* hmac.c */; }; 19 | 56E3CC7412DD138800D58587 /* hmac.h in Headers */ = {isa = PBXBuildFile; fileRef = 56E3CC5012DD138800D58587 /* hmac.h */; }; 20 | 56E3CC7512DD138800D58587 /* sha1.c in Sources */ = {isa = PBXBuildFile; fileRef = 56E3CC5112DD138800D58587 /* sha1.c */; }; 21 | 56E3CC7612DD138800D58587 /* sha1.h in Headers */ = {isa = PBXBuildFile; fileRef = 56E3CC5212DD138800D58587 /* sha1.h */; }; 22 | 56E3CC7712DD138800D58587 /* OACall.h in Headers */ = {isa = PBXBuildFile; fileRef = 56E3CC5312DD138800D58587 /* OACall.h */; settings = {ATTRIBUTES = (Public, ); }; }; 23 | 56E3CC7812DD138800D58587 /* OACall.m in Sources */ = {isa = PBXBuildFile; fileRef = 56E3CC5412DD138800D58587 /* OACall.m */; }; 24 | 56E3CC7912DD138800D58587 /* OAConsumer.h in Headers */ = {isa = PBXBuildFile; fileRef = 56E3CC5512DD138800D58587 /* OAConsumer.h */; settings = {ATTRIBUTES = (Public, ); }; }; 25 | 56E3CC7A12DD138800D58587 /* OAConsumer.m in Sources */ = {isa = PBXBuildFile; fileRef = 56E3CC5612DD138800D58587 /* OAConsumer.m */; }; 26 | 56E3CC7B12DD138800D58587 /* OADataFetcher.h in Headers */ = {isa = PBXBuildFile; fileRef = 56E3CC5712DD138800D58587 /* OADataFetcher.h */; settings = {ATTRIBUTES = (Public, ); }; }; 27 | 56E3CC7C12DD138800D58587 /* OADataFetcher.m in Sources */ = {isa = PBXBuildFile; fileRef = 56E3CC5812DD138800D58587 /* OADataFetcher.m */; }; 28 | 56E3CC7D12DD138800D58587 /* OAHMAC_SHA1SignatureProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = 56E3CC5912DD138800D58587 /* OAHMAC_SHA1SignatureProvider.h */; settings = {ATTRIBUTES = (Public, ); }; }; 29 | 56E3CC7E12DD138800D58587 /* OAHMAC_SHA1SignatureProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = 56E3CC5A12DD138800D58587 /* OAHMAC_SHA1SignatureProvider.m */; }; 30 | 56E3CC7F12DD138800D58587 /* OAMutableURLRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = 56E3CC5B12DD138800D58587 /* OAMutableURLRequest.h */; settings = {ATTRIBUTES = (Public, ); }; }; 31 | 56E3CC8012DD138800D58587 /* OAMutableURLRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 56E3CC5C12DD138800D58587 /* OAMutableURLRequest.m */; }; 32 | 56E3CC8112DD138800D58587 /* OAPlaintextSignatureProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = 56E3CC5D12DD138800D58587 /* OAPlaintextSignatureProvider.h */; settings = {ATTRIBUTES = (Public, ); }; }; 33 | 56E3CC8212DD138800D58587 /* OAPlaintextSignatureProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = 56E3CC5E12DD138800D58587 /* OAPlaintextSignatureProvider.m */; }; 34 | 56E3CC8312DD138800D58587 /* OAProblem.h in Headers */ = {isa = PBXBuildFile; fileRef = 56E3CC5F12DD138800D58587 /* OAProblem.h */; settings = {ATTRIBUTES = (Public, ); }; }; 35 | 56E3CC8412DD138800D58587 /* OAProblem.m in Sources */ = {isa = PBXBuildFile; fileRef = 56E3CC6012DD138800D58587 /* OAProblem.m */; }; 36 | 56E3CC8512DD138800D58587 /* OARequestParameter.h in Headers */ = {isa = PBXBuildFile; fileRef = 56E3CC6112DD138800D58587 /* OARequestParameter.h */; settings = {ATTRIBUTES = (Public, ); }; }; 37 | 56E3CC8612DD138800D58587 /* OARequestParameter.m in Sources */ = {isa = PBXBuildFile; fileRef = 56E3CC6212DD138800D58587 /* OARequestParameter.m */; }; 38 | 56E3CC8712DD138800D58587 /* OAServiceTicket.h in Headers */ = {isa = PBXBuildFile; fileRef = 56E3CC6312DD138800D58587 /* OAServiceTicket.h */; settings = {ATTRIBUTES = (Public, ); }; }; 39 | 56E3CC8812DD138800D58587 /* OAServiceTicket.m in Sources */ = {isa = PBXBuildFile; fileRef = 56E3CC6412DD138800D58587 /* OAServiceTicket.m */; }; 40 | 56E3CC8912DD138800D58587 /* OASignatureProviding.h in Headers */ = {isa = PBXBuildFile; fileRef = 56E3CC6512DD138800D58587 /* OASignatureProviding.h */; settings = {ATTRIBUTES = (Public, ); }; }; 41 | 56E3CC8A12DD138800D58587 /* OAToken.h in Headers */ = {isa = PBXBuildFile; fileRef = 56E3CC6612DD138800D58587 /* OAToken.h */; settings = {ATTRIBUTES = (Public, ); }; }; 42 | 56E3CC8B12DD138800D58587 /* OAToken.m in Sources */ = {isa = PBXBuildFile; fileRef = 56E3CC6712DD138800D58587 /* OAToken.m */; }; 43 | 56E3CC8C12DD138800D58587 /* OATokenManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 56E3CC6812DD138800D58587 /* OATokenManager.h */; settings = {ATTRIBUTES = (Public, ); }; }; 44 | 56E3CC8D12DD138800D58587 /* OATokenManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 56E3CC6912DD138800D58587 /* OATokenManager.m */; }; 45 | 56E3CC8E12DD138800D58587 /* OAuthConsumer.h in Headers */ = {isa = PBXBuildFile; fileRef = 56E3CC6A12DD138800D58587 /* OAuthConsumer.h */; settings = {ATTRIBUTES = (Public, ); }; }; 46 | AA747D9F0F9514B9006C5449 /* OAuthConsumer_Prefix.pch in Headers */ = {isa = PBXBuildFile; fileRef = AA747D9E0F9514B9006C5449 /* OAuthConsumer_Prefix.pch */; }; 47 | AACBBE4A0F95108600F1A2B1 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AACBBE490F95108600F1A2B1 /* Foundation.framework */; }; 48 | /* End PBXBuildFile section */ 49 | 50 | /* Begin PBXFileReference section */ 51 | 56E3CC4612DD138800D58587 /* NSMutableURLRequest+Parameters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSMutableURLRequest+Parameters.h"; sourceTree = ""; }; 52 | 56E3CC4712DD138800D58587 /* NSMutableURLRequest+Parameters.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSMutableURLRequest+Parameters.m"; sourceTree = ""; }; 53 | 56E3CC4812DD138800D58587 /* NSString+URLEncoding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+URLEncoding.h"; sourceTree = ""; }; 54 | 56E3CC4912DD138800D58587 /* NSString+URLEncoding.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+URLEncoding.m"; sourceTree = ""; }; 55 | 56E3CC4A12DD138800D58587 /* NSURL+Base.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSURL+Base.h"; sourceTree = ""; }; 56 | 56E3CC4B12DD138800D58587 /* NSURL+Base.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSURL+Base.m"; sourceTree = ""; }; 57 | 56E3CC4D12DD138800D58587 /* Base64Transcoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = Base64Transcoder.c; sourceTree = ""; }; 58 | 56E3CC4E12DD138800D58587 /* Base64Transcoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Base64Transcoder.h; sourceTree = ""; }; 59 | 56E3CC4F12DD138800D58587 /* hmac.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = hmac.c; sourceTree = ""; }; 60 | 56E3CC5012DD138800D58587 /* hmac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = hmac.h; sourceTree = ""; }; 61 | 56E3CC5112DD138800D58587 /* sha1.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sha1.c; sourceTree = ""; }; 62 | 56E3CC5212DD138800D58587 /* sha1.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sha1.h; sourceTree = ""; }; 63 | 56E3CC5312DD138800D58587 /* OACall.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OACall.h; sourceTree = ""; }; 64 | 56E3CC5412DD138800D58587 /* OACall.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OACall.m; sourceTree = ""; }; 65 | 56E3CC5512DD138800D58587 /* OAConsumer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OAConsumer.h; sourceTree = ""; }; 66 | 56E3CC5612DD138800D58587 /* OAConsumer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OAConsumer.m; sourceTree = ""; }; 67 | 56E3CC5712DD138800D58587 /* OADataFetcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OADataFetcher.h; sourceTree = ""; }; 68 | 56E3CC5812DD138800D58587 /* OADataFetcher.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OADataFetcher.m; sourceTree = ""; }; 69 | 56E3CC5912DD138800D58587 /* OAHMAC_SHA1SignatureProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OAHMAC_SHA1SignatureProvider.h; sourceTree = ""; }; 70 | 56E3CC5A12DD138800D58587 /* OAHMAC_SHA1SignatureProvider.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OAHMAC_SHA1SignatureProvider.m; sourceTree = ""; }; 71 | 56E3CC5B12DD138800D58587 /* OAMutableURLRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OAMutableURLRequest.h; sourceTree = ""; }; 72 | 56E3CC5C12DD138800D58587 /* OAMutableURLRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OAMutableURLRequest.m; sourceTree = ""; }; 73 | 56E3CC5D12DD138800D58587 /* OAPlaintextSignatureProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OAPlaintextSignatureProvider.h; sourceTree = ""; }; 74 | 56E3CC5E12DD138800D58587 /* OAPlaintextSignatureProvider.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OAPlaintextSignatureProvider.m; sourceTree = ""; }; 75 | 56E3CC5F12DD138800D58587 /* OAProblem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OAProblem.h; sourceTree = ""; }; 76 | 56E3CC6012DD138800D58587 /* OAProblem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OAProblem.m; sourceTree = ""; }; 77 | 56E3CC6112DD138800D58587 /* OARequestParameter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OARequestParameter.h; sourceTree = ""; }; 78 | 56E3CC6212DD138800D58587 /* OARequestParameter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OARequestParameter.m; sourceTree = ""; }; 79 | 56E3CC6312DD138800D58587 /* OAServiceTicket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OAServiceTicket.h; sourceTree = ""; }; 80 | 56E3CC6412DD138800D58587 /* OAServiceTicket.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OAServiceTicket.m; sourceTree = ""; }; 81 | 56E3CC6512DD138800D58587 /* OASignatureProviding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OASignatureProviding.h; sourceTree = ""; }; 82 | 56E3CC6612DD138800D58587 /* OAToken.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OAToken.h; sourceTree = ""; }; 83 | 56E3CC6712DD138800D58587 /* OAToken.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OAToken.m; sourceTree = ""; }; 84 | 56E3CC6812DD138800D58587 /* OATokenManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OATokenManager.h; sourceTree = ""; }; 85 | 56E3CC6912DD138800D58587 /* OATokenManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OATokenManager.m; sourceTree = ""; }; 86 | 56E3CC6A12DD138800D58587 /* OAuthConsumer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OAuthConsumer.h; sourceTree = ""; }; 87 | AA747D9E0F9514B9006C5449 /* OAuthConsumer_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OAuthConsumer_Prefix.pch; sourceTree = SOURCE_ROOT; }; 88 | AACBBE490F95108600F1A2B1 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 89 | D2AAC07E0554694100DB518D /* libOAuthConsumer.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libOAuthConsumer.a; sourceTree = BUILT_PRODUCTS_DIR; }; 90 | /* End PBXFileReference section */ 91 | 92 | /* Begin PBXFrameworksBuildPhase section */ 93 | D2AAC07C0554694100DB518D /* Frameworks */ = { 94 | isa = PBXFrameworksBuildPhase; 95 | buildActionMask = 2147483647; 96 | files = ( 97 | AACBBE4A0F95108600F1A2B1 /* Foundation.framework in Frameworks */, 98 | ); 99 | runOnlyForDeploymentPostprocessing = 0; 100 | }; 101 | /* End PBXFrameworksBuildPhase section */ 102 | 103 | /* Begin PBXGroup section */ 104 | 034768DFFF38A50411DB9C8B /* Products */ = { 105 | isa = PBXGroup; 106 | children = ( 107 | D2AAC07E0554694100DB518D /* libOAuthConsumer.a */, 108 | ); 109 | name = Products; 110 | sourceTree = ""; 111 | }; 112 | 0867D691FE84028FC02AAC07 /* OAuthConsumer */ = { 113 | isa = PBXGroup; 114 | children = ( 115 | 08FB77AEFE84172EC02AAC07 /* Classes */, 116 | 32C88DFF0371C24200C91783 /* Other Sources */, 117 | 0867D69AFE84028FC02AAC07 /* Frameworks */, 118 | 034768DFFF38A50411DB9C8B /* Products */, 119 | ); 120 | name = OAuthConsumer; 121 | sourceTree = ""; 122 | }; 123 | 0867D69AFE84028FC02AAC07 /* Frameworks */ = { 124 | isa = PBXGroup; 125 | children = ( 126 | AACBBE490F95108600F1A2B1 /* Foundation.framework */, 127 | ); 128 | name = Frameworks; 129 | sourceTree = ""; 130 | }; 131 | 08FB77AEFE84172EC02AAC07 /* Classes */ = { 132 | isa = PBXGroup; 133 | children = ( 134 | 56E3CC4512DD138800D58587 /* Categories */, 135 | 56E3CC4C12DD138800D58587 /* Crypto */, 136 | 56E3CC5312DD138800D58587 /* OACall.h */, 137 | 56E3CC5412DD138800D58587 /* OACall.m */, 138 | 56E3CC5512DD138800D58587 /* OAConsumer.h */, 139 | 56E3CC5612DD138800D58587 /* OAConsumer.m */, 140 | 56E3CC5712DD138800D58587 /* OADataFetcher.h */, 141 | 56E3CC5812DD138800D58587 /* OADataFetcher.m */, 142 | 56E3CC5912DD138800D58587 /* OAHMAC_SHA1SignatureProvider.h */, 143 | 56E3CC5A12DD138800D58587 /* OAHMAC_SHA1SignatureProvider.m */, 144 | 56E3CC5B12DD138800D58587 /* OAMutableURLRequest.h */, 145 | 56E3CC5C12DD138800D58587 /* OAMutableURLRequest.m */, 146 | 56E3CC5D12DD138800D58587 /* OAPlaintextSignatureProvider.h */, 147 | 56E3CC5E12DD138800D58587 /* OAPlaintextSignatureProvider.m */, 148 | 56E3CC5F12DD138800D58587 /* OAProblem.h */, 149 | 56E3CC6012DD138800D58587 /* OAProblem.m */, 150 | 56E3CC6112DD138800D58587 /* OARequestParameter.h */, 151 | 56E3CC6212DD138800D58587 /* OARequestParameter.m */, 152 | 56E3CC6312DD138800D58587 /* OAServiceTicket.h */, 153 | 56E3CC6412DD138800D58587 /* OAServiceTicket.m */, 154 | 56E3CC6512DD138800D58587 /* OASignatureProviding.h */, 155 | 56E3CC6612DD138800D58587 /* OAToken.h */, 156 | 56E3CC6712DD138800D58587 /* OAToken.m */, 157 | 56E3CC6812DD138800D58587 /* OATokenManager.h */, 158 | 56E3CC6912DD138800D58587 /* OATokenManager.m */, 159 | 56E3CC6A12DD138800D58587 /* OAuthConsumer.h */, 160 | ); 161 | name = Classes; 162 | sourceTree = ""; 163 | }; 164 | 32C88DFF0371C24200C91783 /* Other Sources */ = { 165 | isa = PBXGroup; 166 | children = ( 167 | AA747D9E0F9514B9006C5449 /* OAuthConsumer_Prefix.pch */, 168 | ); 169 | name = "Other Sources"; 170 | sourceTree = ""; 171 | }; 172 | 56E3CC4512DD138800D58587 /* Categories */ = { 173 | isa = PBXGroup; 174 | children = ( 175 | 56E3CC4612DD138800D58587 /* NSMutableURLRequest+Parameters.h */, 176 | 56E3CC4712DD138800D58587 /* NSMutableURLRequest+Parameters.m */, 177 | 56E3CC4812DD138800D58587 /* NSString+URLEncoding.h */, 178 | 56E3CC4912DD138800D58587 /* NSString+URLEncoding.m */, 179 | 56E3CC4A12DD138800D58587 /* NSURL+Base.h */, 180 | 56E3CC4B12DD138800D58587 /* NSURL+Base.m */, 181 | ); 182 | path = Categories; 183 | sourceTree = ""; 184 | }; 185 | 56E3CC4C12DD138800D58587 /* Crypto */ = { 186 | isa = PBXGroup; 187 | children = ( 188 | 56E3CC4D12DD138800D58587 /* Base64Transcoder.c */, 189 | 56E3CC4E12DD138800D58587 /* Base64Transcoder.h */, 190 | 56E3CC4F12DD138800D58587 /* hmac.c */, 191 | 56E3CC5012DD138800D58587 /* hmac.h */, 192 | 56E3CC5112DD138800D58587 /* sha1.c */, 193 | 56E3CC5212DD138800D58587 /* sha1.h */, 194 | ); 195 | path = Crypto; 196 | sourceTree = ""; 197 | }; 198 | /* End PBXGroup section */ 199 | 200 | /* Begin PBXHeadersBuildPhase section */ 201 | D2AAC07A0554694100DB518D /* Headers */ = { 202 | isa = PBXHeadersBuildPhase; 203 | buildActionMask = 2147483647; 204 | files = ( 205 | AA747D9F0F9514B9006C5449 /* OAuthConsumer_Prefix.pch in Headers */, 206 | 56E3CC6B12DD138800D58587 /* NSMutableURLRequest+Parameters.h in Headers */, 207 | 56E3CC6D12DD138800D58587 /* NSString+URLEncoding.h in Headers */, 208 | 56E3CC6F12DD138800D58587 /* NSURL+Base.h in Headers */, 209 | 56E3CC7212DD138800D58587 /* Base64Transcoder.h in Headers */, 210 | 56E3CC7412DD138800D58587 /* hmac.h in Headers */, 211 | 56E3CC7612DD138800D58587 /* sha1.h in Headers */, 212 | 56E3CC7712DD138800D58587 /* OACall.h in Headers */, 213 | 56E3CC7912DD138800D58587 /* OAConsumer.h in Headers */, 214 | 56E3CC7B12DD138800D58587 /* OADataFetcher.h in Headers */, 215 | 56E3CC7D12DD138800D58587 /* OAHMAC_SHA1SignatureProvider.h in Headers */, 216 | 56E3CC7F12DD138800D58587 /* OAMutableURLRequest.h in Headers */, 217 | 56E3CC8112DD138800D58587 /* OAPlaintextSignatureProvider.h in Headers */, 218 | 56E3CC8312DD138800D58587 /* OAProblem.h in Headers */, 219 | 56E3CC8512DD138800D58587 /* OARequestParameter.h in Headers */, 220 | 56E3CC8712DD138800D58587 /* OAServiceTicket.h in Headers */, 221 | 56E3CC8912DD138800D58587 /* OASignatureProviding.h in Headers */, 222 | 56E3CC8A12DD138800D58587 /* OAToken.h in Headers */, 223 | 56E3CC8C12DD138800D58587 /* OATokenManager.h in Headers */, 224 | 56E3CC8E12DD138800D58587 /* OAuthConsumer.h in Headers */, 225 | ); 226 | runOnlyForDeploymentPostprocessing = 0; 227 | }; 228 | /* End PBXHeadersBuildPhase section */ 229 | 230 | /* Begin PBXNativeTarget section */ 231 | D2AAC07D0554694100DB518D /* OAuthConsumer */ = { 232 | isa = PBXNativeTarget; 233 | buildConfigurationList = 1DEB921E08733DC00010E9CD /* Build configuration list for PBXNativeTarget "OAuthConsumer" */; 234 | buildPhases = ( 235 | D2AAC07A0554694100DB518D /* Headers */, 236 | D2AAC07B0554694100DB518D /* Sources */, 237 | D2AAC07C0554694100DB518D /* Frameworks */, 238 | ); 239 | buildRules = ( 240 | ); 241 | dependencies = ( 242 | ); 243 | name = OAuthConsumer; 244 | productName = OAuthConsumer; 245 | productReference = D2AAC07E0554694100DB518D /* libOAuthConsumer.a */; 246 | productType = "com.apple.product-type.library.static"; 247 | }; 248 | /* End PBXNativeTarget section */ 249 | 250 | /* Begin PBXProject section */ 251 | 0867D690FE84028FC02AAC07 /* Project object */ = { 252 | isa = PBXProject; 253 | buildConfigurationList = 1DEB922208733DC00010E9CD /* Build configuration list for PBXProject "OAuthConsumer" */; 254 | compatibilityVersion = "Xcode 3.1"; 255 | developmentRegion = English; 256 | hasScannedForEncodings = 1; 257 | knownRegions = ( 258 | English, 259 | Japanese, 260 | French, 261 | German, 262 | ); 263 | mainGroup = 0867D691FE84028FC02AAC07 /* OAuthConsumer */; 264 | productRefGroup = 034768DFFF38A50411DB9C8B /* Products */; 265 | projectDirPath = ""; 266 | projectRoot = ""; 267 | targets = ( 268 | D2AAC07D0554694100DB518D /* OAuthConsumer */, 269 | ); 270 | }; 271 | /* End PBXProject section */ 272 | 273 | /* Begin PBXSourcesBuildPhase section */ 274 | D2AAC07B0554694100DB518D /* Sources */ = { 275 | isa = PBXSourcesBuildPhase; 276 | buildActionMask = 2147483647; 277 | files = ( 278 | 56E3CC6C12DD138800D58587 /* NSMutableURLRequest+Parameters.m in Sources */, 279 | 56E3CC6E12DD138800D58587 /* NSString+URLEncoding.m in Sources */, 280 | 56E3CC7012DD138800D58587 /* NSURL+Base.m in Sources */, 281 | 56E3CC7112DD138800D58587 /* Base64Transcoder.c in Sources */, 282 | 56E3CC7312DD138800D58587 /* hmac.c in Sources */, 283 | 56E3CC7512DD138800D58587 /* sha1.c in Sources */, 284 | 56E3CC7812DD138800D58587 /* OACall.m in Sources */, 285 | 56E3CC7A12DD138800D58587 /* OAConsumer.m in Sources */, 286 | 56E3CC7C12DD138800D58587 /* OADataFetcher.m in Sources */, 287 | 56E3CC7E12DD138800D58587 /* OAHMAC_SHA1SignatureProvider.m in Sources */, 288 | 56E3CC8012DD138800D58587 /* OAMutableURLRequest.m in Sources */, 289 | 56E3CC8212DD138800D58587 /* OAPlaintextSignatureProvider.m in Sources */, 290 | 56E3CC8412DD138800D58587 /* OAProblem.m in Sources */, 291 | 56E3CC8612DD138800D58587 /* OARequestParameter.m in Sources */, 292 | 56E3CC8812DD138800D58587 /* OAServiceTicket.m in Sources */, 293 | 56E3CC8B12DD138800D58587 /* OAToken.m in Sources */, 294 | 56E3CC8D12DD138800D58587 /* OATokenManager.m in Sources */, 295 | ); 296 | runOnlyForDeploymentPostprocessing = 0; 297 | }; 298 | /* End PBXSourcesBuildPhase section */ 299 | 300 | /* Begin XCBuildConfiguration section */ 301 | 1DEB921F08733DC00010E9CD /* Debug */ = { 302 | isa = XCBuildConfiguration; 303 | buildSettings = { 304 | ALWAYS_SEARCH_USER_PATHS = NO; 305 | ARCHS = "$(ARCHS_STANDARD_32_BIT)"; 306 | COPY_PHASE_STRIP = NO; 307 | DSTROOT = /tmp/OAuthConsumer.dst; 308 | GCC_DYNAMIC_NO_PIC = NO; 309 | GCC_ENABLE_FIX_AND_CONTINUE = YES; 310 | GCC_MODEL_TUNING = G5; 311 | GCC_OPTIMIZATION_LEVEL = 0; 312 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 313 | GCC_PREFIX_HEADER = OAuthConsumer_Prefix.pch; 314 | INSTALL_PATH = /usr/local/lib; 315 | PRODUCT_NAME = OAuthConsumer; 316 | }; 317 | name = Debug; 318 | }; 319 | 1DEB922008733DC00010E9CD /* Release */ = { 320 | isa = XCBuildConfiguration; 321 | buildSettings = { 322 | ALWAYS_SEARCH_USER_PATHS = NO; 323 | ARCHS = "$(ARCHS_STANDARD_32_BIT)"; 324 | DSTROOT = /tmp/OAuthConsumer.dst; 325 | GCC_MODEL_TUNING = G5; 326 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 327 | GCC_PREFIX_HEADER = OAuthConsumer_Prefix.pch; 328 | INSTALL_PATH = /usr/local/lib; 329 | PRODUCT_NAME = OAuthConsumer; 330 | }; 331 | name = Release; 332 | }; 333 | 1DEB922308733DC00010E9CD /* Debug */ = { 334 | isa = XCBuildConfiguration; 335 | buildSettings = { 336 | ARCHS = "$(ARCHS_STANDARD_32_BIT)"; 337 | GCC_C_LANGUAGE_STANDARD = c99; 338 | GCC_OPTIMIZATION_LEVEL = 0; 339 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 340 | GCC_WARN_UNUSED_VARIABLE = YES; 341 | OTHER_LDFLAGS = "-ObjC"; 342 | PREBINDING = NO; 343 | SDKROOT = iphoneos; 344 | }; 345 | name = Debug; 346 | }; 347 | 1DEB922408733DC00010E9CD /* Release */ = { 348 | isa = XCBuildConfiguration; 349 | buildSettings = { 350 | ARCHS = "$(ARCHS_STANDARD_32_BIT)"; 351 | GCC_C_LANGUAGE_STANDARD = c99; 352 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 353 | GCC_WARN_UNUSED_VARIABLE = YES; 354 | OTHER_LDFLAGS = "-ObjC"; 355 | PREBINDING = NO; 356 | SDKROOT = iphoneos; 357 | }; 358 | name = Release; 359 | }; 360 | /* End XCBuildConfiguration section */ 361 | 362 | /* Begin XCConfigurationList section */ 363 | 1DEB921E08733DC00010E9CD /* Build configuration list for PBXNativeTarget "OAuthConsumer" */ = { 364 | isa = XCConfigurationList; 365 | buildConfigurations = ( 366 | 1DEB921F08733DC00010E9CD /* Debug */, 367 | 1DEB922008733DC00010E9CD /* Release */, 368 | ); 369 | defaultConfigurationIsVisible = 0; 370 | defaultConfigurationName = Release; 371 | }; 372 | 1DEB922208733DC00010E9CD /* Build configuration list for PBXProject "OAuthConsumer" */ = { 373 | isa = XCConfigurationList; 374 | buildConfigurations = ( 375 | 1DEB922308733DC00010E9CD /* Debug */, 376 | 1DEB922408733DC00010E9CD /* Release */, 377 | ); 378 | defaultConfigurationIsVisible = 0; 379 | defaultConfigurationName = Release; 380 | }; 381 | /* End XCConfigurationList section */ 382 | }; 383 | rootObject = 0867D690FE84028FC02AAC07 /* Project object */; 384 | } 385 | --------------------------------------------------------------------------------