summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am2
-rw-r--r--src/Makefile.in1
-rw-r--r--src/config.h2
-rw-r--r--src/hash.c8
-rw-r--r--src/oauth.c85
-rw-r--r--src/oauth.h70
-rw-r--r--src/oauth_http.c53
-rw-r--r--src/sha1.c325
-rw-r--r--src/xmalloc.c3
-rw-r--r--src/xmalloc.h1
10 files changed, 467 insertions, 83 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index b59c7c7..ddcdce1 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -6,3 +6,5 @@ liboauth_la_SOURCES=oauth.c config.h hash.c xmalloc.c xmalloc.h oauth_http.c
liboauth_la_LDFLAGS=@LIBOAUTH_LDFLAGS@ -version-info @VERSION_INFO@
liboauth_la_LIBADD=@HASH_LIBS@ @CURL_LIBS@
liboauth_la_CFLAGS=@LIBOAUTH_CFLAGS@ @HASH_CFLAGS@ @CURL_CFLAGS@
+
+EXTRA_DIST= sha1.c
diff --git a/src/Makefile.in b/src/Makefile.in
index 712f27a..c19d294 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -252,6 +252,7 @@ liboauth_la_SOURCES = oauth.c config.h hash.c xmalloc.c xmalloc.h oauth_http.c
liboauth_la_LDFLAGS = @LIBOAUTH_LDFLAGS@ -version-info @VERSION_INFO@
liboauth_la_LIBADD = @HASH_LIBS@ @CURL_LIBS@
liboauth_la_CFLAGS = @LIBOAUTH_CFLAGS@ @HASH_CFLAGS@ @CURL_CFLAGS@
+EXTRA_DIST = sha1.c
all: config.h
$(MAKE) $(AM_MAKEFLAGS) all-am
diff --git a/src/config.h b/src/config.h
index c875459..f5d7605 100644
--- a/src/config.h
+++ b/src/config.h
@@ -157,7 +157,7 @@
/* #undef USE_NSS */
/* Version number of package */
-#define VERSION "0.9.7"
+#define VERSION "1.0.3"
/* Define to `unsigned int' if <sys/types.h> does not define. */
/* #undef size_t */
diff --git a/src/hash.c b/src/hash.c
index fe319dd..17ff5c8 100644
--- a/src/hash.c
+++ b/src/hash.c
@@ -1,7 +1,7 @@
/*
* hash algorithms used in OAuth
*
- * Copyright 2007-2010 Robin Gareus <robin@gareus.org>
+ * Copyright 2007-2012 Robin Gareus <robin@gareus.org>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -219,7 +219,7 @@ char *oauth_sign_rsa_sha1 (const char *m, const char *k) {
looser:
if (pkey) SECKEY_DestroyPrivateKey(pkey);
if (slot) PK11_FreeSlot(slot);
- free(key);
+ xfree(key);
return rv;
}
@@ -259,7 +259,7 @@ int oauth_verify_rsa_sha1 (const char *m, const char *c, const char *sig) {
looser:
if (pkey) SECKEY_DestroyPublicKey(pkey);
if (slot) PK11_FreeSlot(slot);
- free(key);
+ xfree(key);
return rv;
}
@@ -445,7 +445,7 @@ int oauth_verify_rsa_sha1 (const char *m, const char *c, const char *s) {
err = EVP_VerifyFinal(&md_ctx, b64d, slen, pkey);
EVP_MD_CTX_cleanup(&md_ctx);
EVP_PKEY_free(pkey);
- free(b64d);
+ xfree(b64d);
return (err);
}
diff --git a/src/oauth.c b/src/oauth.c
index d3f7f29..9529e2a 100644
--- a/src/oauth.c
+++ b/src/oauth.c
@@ -1,7 +1,7 @@
/*
* OAuth string functions in POSIX-C.
*
- * Copyright 2007-2011 Robin Gareus <robin@gareus.org>
+ * Copyright 2007-2013 Robin Gareus <robin@gareus.org>
*
* The base64 functions are by Jan-Henrik Haukeland, <hauk@tildeslash.com>
* and un/escape_url() was inspired by libcurl's curl_escape under ISC-license
@@ -30,7 +30,7 @@
# include <config.h>
#endif
-#define WIPE_MEMORY ///< overwrite sensitve data before free()ing it.
+#define WIPE_MEMORY ///< overwrite sensitve data before xfree()ing it.
#include <stdio.h>
#include <stdarg.h>
@@ -167,7 +167,7 @@ int oauth_decode_base64(unsigned char *dest, const char *src) {
if(c3 != '=') *p++=(((b2&0xf)<<4)|(b3>>2) );
if(c4 != '=') *p++=(((b3&0x3)<<6)|b4 );
}
- free(buf);
+ xfree(buf);
dest[p-dest]='\0';
return(p-dest);
}
@@ -285,7 +285,7 @@ char *oauth_url_unescape(const char *string, size_t *olen) {
* @return signature string
*/
char *oauth_sign_plaintext (const char *m, const char *k) {
- return(strdup(k));
+ return(xstrdup(k));
}
/**
@@ -298,7 +298,7 @@ char *oauth_sign_plaintext (const char *m, const char *k) {
* @param ... string to escape and added (may be NULL)
*
* @return pointer to memory holding the concatenated
- * strings - needs to be free(d) by the caller. or NULL
+ * strings - needs to be xfree(d) by the caller. or NULL
* in case we ran out of memory.
*/
char *oauth_catenc(int len, ...) {
@@ -314,12 +314,12 @@ char *oauth_catenc(int len, ...) {
enc = oauth_url_escape(arg);
if(!enc) break;
len = strlen(enc) + 1 + ((i>0)?1:0);
- if(rv) len+=strlen(rv);
+ len+=strlen(rv);
rv=(char*) xrealloc(rv,len*sizeof(char));
if(i>0) strcat(rv, "&");
strcat(rv, enc);
- free(enc);
+ xfree(enc);
}
va_end(va);
return(rv);
@@ -383,7 +383,7 @@ int oauth_split_post_paramters(const char *url, char ***argv, short qesc) {
#ifdef DEBUG_OAUTH
fprintf(stderr, "\nliboauth: added trailing slash to URL: '%s'\n\n", token);
#endif
- free((*argv)[argc]);
+ xfree((*argv)[argc]);
(*argv)[argc]= (char*) xmalloc(sizeof(char)*(2+strlen(token)));
strcpy((*argv)[argc],token);
strcat((*argv)[argc],"/");
@@ -396,7 +396,7 @@ int oauth_split_post_paramters(const char *url, char ***argv, short qesc) {
argc++;
}
- free(t1);
+ xfree(t1);
return argc;
}
@@ -442,7 +442,7 @@ char *oauth_serialize_url_sep (int argc, int start, char **argv, char *sep, int
if ((mod&1)==1 && (strncmp(argv[i],"oauth_",6) == 0 || strncmp(argv[i],"x_oauth_",8) == 0) ) continue;
if ((mod&2)==2 && (strncmp(argv[i],"oauth_",6) != 0 && strncmp(argv[i],"x_oauth_",8) != 0) && i!=0) continue;
- if (query) len+=strlen(query);
+ len+=strlen(query);
if (i==start && i==0 && strstr(argv[i], ":/")) {
tmp=xstrdup(argv[i]);
@@ -456,7 +456,7 @@ char *oauth_serialize_url_sep (int argc, int start, char **argv, char *sep, int
strcpy(t2, tmp);
strcpy(t2+off+2, tmp+off);
*(t2+off)='%'; *(t2+off+1)='2'; *(t2+off+2)='0';
- free(tmp);
+ xfree(tmp);
tmp=t2;
# endif
#endif
@@ -479,7 +479,7 @@ char *oauth_serialize_url_sep (int argc, int start, char **argv, char *sep, int
if (mod&4) strcat(tmp,"\"");
strcat(tmp,t1);
if (mod&4) strcat(tmp,"\"");
- free(t1);
+ xfree(t1);
len+=strlen(tmp);
}
len+=seplen+1;
@@ -491,7 +491,7 @@ char *oauth_serialize_url_sep (int argc, int start, char **argv, char *sep, int
strcat(query, "?");
first=1;
}
- free(tmp);
+ xfree(tmp);
}
return (query);
}
@@ -588,6 +588,7 @@ int oauth_cmpstringp(const void *p1, const void *p2) {
char *v1,*v2;
char *t1,*t2;
int rv;
+ if (!p1 || !p2) return 0;
// TODO: this is not fast - we should escape the
// array elements (once) before sorting.
v1=oauth_url_escape(* (char * const *)p1);
@@ -603,9 +604,9 @@ int oauth_cmpstringp(const void *p1, const void *p2) {
// compare parameter names
rv=strcmp(v1,v2);
- if (rv!=0) {
- if (v1) free(v1);
- if (v2) free(v2);
+ if (rv != 0) {
+ xfree(v1);
+ xfree(v2);
return rv;
}
@@ -617,8 +618,8 @@ int oauth_cmpstringp(const void *p1, const void *p2) {
else if (!t1) rv=-1;
else rv=1;
- if (v1) free(v1);
- if (v2) free(v2);
+ xfree(v1);
+ xfree(v2);
return rv;
}
@@ -665,7 +666,7 @@ void oauth_add_protocol(int *argcp, char ***argvp,
char *tmp;
snprintf(oarg, 1024, "oauth_nonce=%s", (tmp=oauth_gen_nonce()));
oauth_add_param_to_array(argcp, argvp, oarg);
- free(tmp);
+ xfree(tmp);
}
if (!oauth_param_exists(*argvp,*argcp,"oauth_timestamp")) {
@@ -784,14 +785,36 @@ void oauth_sign_array2_process (int *argcp, char***argvp,
// serialize URL - base-url
query= oauth_serialize_url_parameters(*argcp, *argvp);
- // generate signature
- okey = oauth_catenc(2, c_secret, t_secret);
+ // prepare data to sign
+ if (method == OA_RSA) {
+ size_t len = 1;
+ if (c_secret) {
+ len += strlen(c_secret);
+ }
+ if (t_secret) {
+ len += strlen(t_secret);
+ }
+ okey = (char*)xmalloc(len * sizeof(char));
+ *okey = '\0';
+ if (c_secret) {
+ okey = strcat(okey, c_secret);
+ }
+ if (t_secret) {
+ okey = strcat(okey, t_secret);
+ }
+ } else {
+ okey = oauth_catenc(2, c_secret, t_secret);
+ }
+
odat = oauth_catenc(3, http_request_method, (*argvp)[0], query); // base-string
- free(http_request_method);
+ xfree(http_request_method);
+
#ifdef DEBUG_OAUTH
fprintf (stderr, "\nliboauth: data to sign='%s'\n\n", odat);
fprintf (stderr, "\nliboauth: key='%s'\n\n", okey);
#endif
+
+ // generate signature
switch(method) {
case OA_RSA:
sign = oauth_sign_rsa_sha1(odat,okey); // XXX okey needs to be RSA key!
@@ -806,14 +829,14 @@ void oauth_sign_array2_process (int *argcp, char***argvp,
memset(okey,0, strlen(okey));
memset(odat,0, strlen(odat));
#endif
- free(odat);
- free(okey);
+ xfree(odat);
+ xfree(okey);
// append signature to query args.
snprintf(oarg, 1024, "oauth_signature=%s",sign);
oauth_add_param_to_array(argcp, argvp, oarg);
- free(sign);
- if(query) free(query);
+ xfree(sign);
+ if(query) xfree(query);
}
char *oauth_sign_array2 (int *argcp, char***argvp,
@@ -845,14 +868,14 @@ char *oauth_sign_array2 (int *argcp, char***argvp,
* free array args
*
* @param argcp pointer to array length int
- * @param argvp pointer to array values to be free()d
+ * @param argvp pointer to array values to be xfree()d
*/
void oauth_free_array(int *argcp, char ***argvp) {
int i;
for (i=0;i<(*argcp);i++) {
- free((*argvp)[i]);
+ xfree((*argvp)[i]);
}
- if(*argvp) free(*argvp);
+ if(*argvp) xfree(*argvp);
}
/**
@@ -863,8 +886,8 @@ char *oauth_body_hash_encode(size_t len, unsigned char *digest) {
char *sign=oauth_encode_base64(len,digest);
char *sig_url = (char*)xmalloc(17+strlen(sign));
sprintf(sig_url,"oauth_body_hash=%s", sign);
- free(sign);
- free(digest);
+ xfree(sign);
+ xfree(digest);
return sig_url;
}
diff --git a/src/oauth.h b/src/oauth.h
index e612554..bb6dc3c 100644
--- a/src/oauth.h
+++ b/src/oauth.h
@@ -3,7 +3,7 @@
* @file oauth.h
* @author Robin Gareus <robin@gareus.org>
*
- * Copyright 2007-2011 Robin Gareus <robin@gareus.org>
+ * Copyright 2007-2014 Robin Gareus <robin@gareus.org>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -29,17 +29,16 @@
#ifndef DOXYGEN_IGNORE
// liboauth version
-#define LIBOAUTH_VERSION "0.9.7"
-#define LIBOAUTH_VERSION_MAJOR 0
-#define LIBOAUTH_VERSION_MINOR 9
-#define LIBOAUTH_VERSION_MICRO 7
+#define LIBOAUTH_VERSION "1.0.3"
+#define LIBOAUTH_VERSION_MAJOR 1
+#define LIBOAUTH_VERSION_MINOR 0
+#define LIBOAUTH_VERSION_MICRO 3
//interface revision number
//http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
#define LIBOAUTH_CUR 8
-#define LIBOAUTH_REV 4
+#define LIBOAUTH_REV 7
#define LIBOAUTH_AGE 8
-#endif
#ifdef __GNUC__
# define OA_GCC_VERSION_AT_LEAST(x,y) (__GNUC__ > x || __GNUC__ == x && __GNUC_MINOR__ >= y)
@@ -55,6 +54,8 @@
#endif
#endif
+#endif /* doxygen ignore */
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -125,7 +126,7 @@ char *oauth_url_unescape(const char *string, size_t *olen);
char *oauth_sign_hmac_sha1 (const char *m, const char *k);
/**
- * same as \ref oauth_sign_hmac_sha1 but allows
+ * same as \ref oauth_sign_hmac_sha1 but allows one
* to specify length of message and key (in case they contain null chars).
*
* @param m message to be signed
@@ -179,7 +180,7 @@ int oauth_verify_rsa_sha1 (const char *m, const char *c, const char *s);
* @param len the number of arguments to follow this parameter
*
* @return pointer to memory holding the concatenated
- * strings - needs to be free(d) by the caller. or NULL
+ * strings - needs to be xfree(d) by the caller. or NULL
* in case we ran out of memory.
*/
char *oauth_catenc(int len, ...);
@@ -208,7 +209,7 @@ int oauth_split_url_parameters(const char *url, char ***argv);
* The array is re-allocated to match the number of parameters and each
* parameter-string is allocated with strdup. - The memory needs to be freed
* by the caller.
- * @param qesc use query parameter escape (vs post-param-escape) - if set
+ * @param qesc use query parameter escape (vs post-param-escape) - if set
* to 1 all '+' are treated as spaces ' '
*
* @return number of parameter(s) in array.
@@ -218,9 +219,9 @@ int oauth_split_post_paramters(const char *url, char ***argv, short qesc);
/**
* build a url query string from an array.
*
- * @param argc the total number of elements in the array
+ * @param argc the total number of elements in the array
* @param start element in the array at which to start concatenating.
- * @param argv parameter-array to concatenate.
+ * @param argv parameter-array to concatenate.
* @return url string needs to be freed by the caller.
*
*/
@@ -295,7 +296,7 @@ void oauth_add_param_to_array(int *argcp, char ***argvp, const char *addparam);
* free array args
*
* @param argcp pointer to array length int
- * @param argvp pointer to array values to be free()d
+ * @param argvp pointer to array values to be xfree()d
*/
void oauth_free_array(int *argcp, char ***argvp);
@@ -394,7 +395,7 @@ char *oauth_sign_url (const char *url, char **postargs,
* The user needs to call /ref oauth_serialize_url (oA)
* and /ref oauth_free_array to do so.
*
- * This allows to split parts of the URL to be used for
+ * This allows one to split parts of the URL to be used for
* OAuth HTTP Authorization header:
* see http://oauth.net/core/1.0a/#consumer_req_param
* the oauthtest2 example code does so.
@@ -565,8 +566,10 @@ char *oauth_sign_xmpp (const char *xml,
* @param q query string to send along with the HTTP request or NULL.
* @return In case of an error NULL is returned; otherwise a pointer to the
* replied content from HTTP server. latter needs to be freed by caller.
+ *
+ * @deprecated use libcurl - http://curl.haxx.se/libcurl/c/
*/
-char *oauth_http_get (const char *u, const char *q);
+char *oauth_http_get (const char *u, const char *q) attribute_deprecated;
/**
* do a HTTP GET request, wait for it to finish
@@ -574,9 +577,8 @@ char *oauth_http_get (const char *u, const char *q);
*
* (requires libcurl)
*
- * This is equivalent to /ref oauth_http_get but allows to
- * specifiy a custom HTTP header and has
- * has no support for commandline-curl.
+ * This is equivalent to /ref oauth_http_get but allows one
+ * to specifiy a custom HTTP header andhas no support for commandline-curl.
*
* If liboauth is compiled <b>without</b> libcurl this function
* always returns NULL.
@@ -587,8 +589,10 @@ char *oauth_http_get (const char *u, const char *q);
* Multiple header elements can be passed separating them with "\r\n"
* @return In case of an error NULL is returned; otherwise a pointer to the
* replied content from HTTP server. latter needs to be freed by caller.
+ *
+ * @deprecated use libcurl - http://curl.haxx.se/libcurl/c/
*/
-char *oauth_http_get2 (const char *u, const char *q, const char *customheader);
+char *oauth_http_get2 (const char *u, const char *q, const char *customheader) attribute_deprecated;
/**
@@ -619,8 +623,10 @@ char *oauth_http_get2 (const char *u, const char *q, const char *customheader);
* @param u url to query
* @param p postargs to send along with the HTTP request.
* @return replied content from HTTP server. needs to be freed by caller.
+ *
+ * @deprecated use libcurl - http://curl.haxx.se/libcurl/c/
*/
-char *oauth_http_post (const char *u, const char *p);
+char *oauth_http_post (const char *u, const char *p) attribute_deprecated;
/**
* do a HTTP POST request, wait for it to finish
@@ -639,8 +645,10 @@ char *oauth_http_post (const char *u, const char *p);
* @param customheader specify custom HTTP header (or NULL for none)
* Multiple header elements can be passed separating them with "\r\n"
* @return replied content from HTTP server. needs to be freed by caller.
+ *
+ * @deprecated use libcurl - http://curl.haxx.se/libcurl/c/
*/
-char *oauth_http_post2 (const char *u, const char *p, const char *customheader);
+char *oauth_http_post2 (const char *u, const char *p, const char *customheader) attribute_deprecated;
/**
@@ -656,8 +664,10 @@ char *oauth_http_post2 (const char *u, const char *p, const char *customheader);
* @param customheader specify custom HTTP header (or NULL for default).
* Multiple header elements can be passed separating them with "\r\n"
* @return returned HTTP reply or NULL on error
+ *
+ * @deprecated use libcurl - http://curl.haxx.se/libcurl/c/
*/
-char *oauth_post_file (const char *u, const char *fn, const size_t len, const char *customheader);
+char *oauth_post_file (const char *u, const char *fn, const size_t len, const char *customheader) attribute_deprecated;
/**
* http post raw data
@@ -672,8 +682,10 @@ char *oauth_post_file (const char *u, const char *fn, const size_t len, const ch
* @param customheader specify custom HTTP header (or NULL for default)
* Multiple header elements can be passed separating them with "\r\n"
* @return returned HTTP reply or NULL on error
+ *
+ * @deprecated use libcurl - http://curl.haxx.se/libcurl/c/
*/
-char *oauth_post_data (const char *u, const char *data, size_t len, const char *customheader);
+char *oauth_post_data (const char *u, const char *data, size_t len, const char *customheader) attribute_deprecated;
/**
* http post raw data, with callback.
@@ -695,13 +707,15 @@ char *oauth_post_data (const char *u, const char *data, size_t len, const char *
* @param callback specify the callback function
* @param callback_data specify data to pass to the callback function
* @return returned HTTP reply or NULL on error
+ *
+ * @deprecated use libcurl - http://curl.haxx.se/libcurl/c/
*/
char *oauth_post_data_with_callback (const char *u,
const char *data,
size_t len,
const char *customheader,
void (*callback)(void*,int,size_t,size_t),
- void *callback_data);
+ void *callback_data) attribute_deprecated;
/**
* http send raw data. similar to /ref oauth_http_post but provides
@@ -719,12 +733,14 @@ char *oauth_post_data_with_callback (const char *u,
* Multiple header elements can be passed separating them with "\r\n"
* @param httpMethod specify http verb ("GET"/"POST"/"PUT"/"DELETE") to be used. if httpMethod is NULL, a POST is executed.
* @return returned HTTP reply or NULL on error
+ *
+ * @deprecated use libcurl - http://curl.haxx.se/libcurl/c/
*/
char *oauth_send_data (const char *u,
const char *data,
size_t len,
const char *customheader,
- const char *httpMethod);
+ const char *httpMethod) attribute_deprecated;
/**
* http post raw data, with callback.
@@ -747,6 +763,8 @@ char *oauth_send_data (const char *u,
* @param callback_data specify data to pass to the callback function
* @param httpMethod specify http verb ("GET"/"POST"/"PUT"/"DELETE") to be used.
* @return returned HTTP reply or NULL on error
+ *
+ * @deprecated use libcurl - http://curl.haxx.se/libcurl/c/
*/
char *oauth_send_data_with_callback (const char *u,
const char *data,
@@ -754,7 +772,7 @@ char *oauth_send_data_with_callback (const char *u,
const char *customheader,
void (*callback)(void*,int,size_t,size_t),
void *callback_data,
- const char *httpMethod);
+ const char *httpMethod) attribute_deprecated;
#ifdef __cplusplus
} /* extern "C" */
diff --git a/src/oauth_http.c b/src/oauth_http.c
index 0e06b10..9d637e1 100644
--- a/src/oauth_http.c
+++ b/src/oauth_http.c
@@ -1,7 +1,7 @@
/*
* OAuth http functions in POSIX-C.
*
- * Copyright 2007, 2008, 2009, 2010 Robin Gareus <robin@gareus.org>
+ * Copyright 2007-2011 Robin Gareus <robin@gareus.org>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -42,7 +42,6 @@
#ifdef HAVE_CURL /* HTTP requests via libcurl */
#include <curl/curl.h>
-#include <sys/stat.h>
# define GLOBAL_CURL_ENVIROMENT_OPTIONS \
if (getenv("CURLOPT_PROXYAUTH")){ \
@@ -180,7 +179,10 @@ char *oauth_curl_get (const char *u, const char *q, const char *customheader) {
chunk.size = 0;
curl = curl_easy_init();
- if(!curl) return NULL;
+ if(!curl) {
+ xfree(t1);
+ return NULL;
+ }
curl_easy_setopt(curl, CURLOPT_URL, q?t1:u);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
@@ -202,7 +204,7 @@ char *oauth_curl_get (const char *u, const char *q, const char *customheader) {
GLOBAL_CURL_ENVIROMENT_OPTIONS;
res = curl_easy_perform(curl);
curl_slist_free_all(slist);
- if (q) free(t1);
+ xfree(t1);
curl_easy_cleanup(curl);
if (res) {
@@ -216,9 +218,10 @@ char *oauth_curl_get (const char *u, const char *q, const char *customheader) {
* the returned string needs to be freed by the caller
*
* @param u url to retrieve
- * @param fn filename of the file to post along
+ * @param fn filename of the file to post along (max 2GB)
* @param len length of the file in bytes. set to '0' for autodetection
* @param customheader specify custom HTTP header (or NULL for default)
+ * the default header adds "Content-Type: image/jpeg;"
* @return returned HTTP or NULL on error
*/
char *oauth_curl_post_file (const char *u, const char *fn, size_t len, const char *customheader) {
@@ -227,6 +230,7 @@ char *oauth_curl_post_file (const char *u, const char *fn, size_t len, const cha
struct curl_slist *slist=NULL;
struct MemoryStruct chunk;
FILE *f;
+ long filelen;
chunk.data=NULL;
chunk.size=0;
@@ -234,19 +238,24 @@ char *oauth_curl_post_file (const char *u, const char *fn, size_t len, const cha
if (customheader)
slist = curl_slist_append(slist, customheader);
else
- slist = curl_slist_append(slist, "Content-Type: image/jpeg;");
-
- if (!len) {
- struct stat statbuf;
- if (stat(fn, &statbuf) == -1) return(NULL);
- len = statbuf.st_size;
- }
+ slist = curl_slist_append(slist, "Content-Type: image/jpeg;"); // good guess :)
f = fopen(fn,"r");
if (!f) return NULL;
+ fseek(f, 0L, SEEK_END);
+ filelen = ftell(f);
+ fseek(f, 0L, SEEK_SET);
+
+ if (!len || len > filelen) {
+ len = filelen;
+ }
+
curl = curl_easy_init();
- if(!curl) return NULL;
+ if(!curl) {
+ fclose(f);
+ return NULL;
+ }
curl_easy_setopt(curl, CURLOPT_URL, u);
curl_easy_setopt(curl, CURLOPT_POST, 1);
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, len);
@@ -262,11 +271,11 @@ char *oauth_curl_post_file (const char *u, const char *fn, size_t len, const cha
GLOBAL_CURL_ENVIROMENT_OPTIONS;
res = curl_easy_perform(curl);
curl_slist_free_all(slist);
+ fclose(f);
if (res) {
// error
return NULL;
}
- fclose(f);
curl_easy_cleanup(curl);
return (chunk.data);
@@ -282,6 +291,7 @@ char *oauth_curl_post_file (const char *u, const char *fn, size_t len, const cha
* @param data data to post along
* @param len length of the file in bytes. set to '0' for autodetection
* @param customheader specify custom HTTP header (or NULL for default)
+ * the default header adds "Content-Type: image/jpeg;"
* @param callback specify the callback function
* @param callback_data specify data to pass to the callback function
* @return returned HTTP reply or NULL on error
@@ -409,7 +419,7 @@ char *oauth_curl_post_data_with_callback (const char *u, const char *data, size_
/**
* escape URL for use in String Quotes (aka shell single quotes).
- * the returned string needs to be free()d by the calling function
+ * the returned string needs to be xfree()d by the calling function
*
* WARNING: this function only escapes single-quotes (')
*
@@ -518,8 +528,8 @@ char *oauth_exec_post (const char *u, const char *p) {
t2=oauth_escape_shell(u);
}
snprintf(cmd, BUFSIZ, cmdtpl, t1, t2);
- free(cmdtpl);
- free(t1); free(t2);
+ xfree(cmdtpl);
+ xfree(t1); xfree(t2);
return oauth_exec_shell(cmd);
}
@@ -551,6 +561,7 @@ char *oauth_exec_get (const char *u, const char *q) {
t1=strstr(cmdtpl, "%u");
if (!t1) {
fprintf(stderr, "\nliboauth: invalid HTTP command. set the '%s' environment variable.\n\n",_OAUTH_ENV_HTTPGET);
+ xfree(cmdtpl);
return(NULL);
}
*(++t1)= 's';
@@ -561,12 +572,12 @@ char *oauth_exec_get (const char *u, const char *q) {
e2 = oauth_escape_shell(q);
t1=(char*)xmalloc(sizeof(char)*(strlen(e1)+strlen(e2)+2));
strcpy(t1,e1); strcat(t1,"?"); strcat(t1,e2);
- free(e2);
+ xfree(e2);
}
snprintf(cmd, BUFSIZ, cmdtpl, q?t1:e1);
- free(cmdtpl);
- free(e1);
- if (q) free(t1);
+ xfree(cmdtpl);
+ xfree(e1);
+ if (q) xfree(t1);
return oauth_exec_shell(cmd);
}
#endif // command-line curl.
diff --git a/src/sha1.c b/src/sha1.c
new file mode 100644
index 0000000..3dae158
--- /dev/null
+++ b/src/sha1.c
@@ -0,0 +1,325 @@
+/* This code is public-domain - it is based on libcrypt
+ * placed in the public domain by Wei Dai and other contributors.
+ */
+// gcc -Wall -DSHA1TEST -o sha1test sha1.c && ./sha1test
+
+#include <stdint.h>
+#include <string.h>
+
+
+#ifdef __BIG_ENDIAN__
+# define SHA_BIG_ENDIAN
+#elif defined __LITTLE_ENDIAN__
+/* override */
+#elif defined __BYTE_ORDER
+# if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+# define SHA_BIG_ENDIAN
+# endif
+#else // ! defined __LITTLE_ENDIAN__
+# include <endian.h> // machine/endian.h
+# if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+# define SHA_BIG_ENDIAN
+# endif
+#endif
+
+
+/* header */
+
+#define HASH_LENGTH 20
+#define BLOCK_LENGTH 64
+
+typedef struct sha1nfo {
+ uint32_t buffer[BLOCK_LENGTH/4];
+ uint32_t state[HASH_LENGTH/4];
+ uint32_t byteCount;
+ uint8_t bufferOffset;
+ uint8_t keyBuffer[BLOCK_LENGTH];
+ uint8_t innerHash[HASH_LENGTH];
+} sha1nfo;
+
+/* public API - prototypes - TODO: doxygen*/
+
+/**
+ */
+void sha1_init(sha1nfo *s);
+/**
+ */
+void sha1_writebyte(sha1nfo *s, uint8_t data);
+/**
+ */
+void sha1_write(sha1nfo *s, const char *data, size_t len);
+/**
+ */
+uint8_t* sha1_result(sha1nfo *s);
+/**
+ */
+void sha1_initHmac(sha1nfo *s, const uint8_t* key, int keyLength);
+/**
+ */
+uint8_t* sha1_resultHmac(sha1nfo *s);
+
+
+/* code */
+#define SHA1_K0 0x5a827999
+#define SHA1_K20 0x6ed9eba1
+#define SHA1_K40 0x8f1bbcdc
+#define SHA1_K60 0xca62c1d6
+
+void sha1_init(sha1nfo *s) {
+ s->state[0] = 0x67452301;
+ s->state[1] = 0xefcdab89;
+ s->state[2] = 0x98badcfe;
+ s->state[3] = 0x10325476;
+ s->state[4] = 0xc3d2e1f0;
+ s->byteCount = 0;
+ s->bufferOffset = 0;
+}
+
+uint32_t sha1_rol32(uint32_t number, uint8_t bits) {
+ return ((number << bits) | (number >> (32-bits)));
+}
+
+void sha1_hashBlock(sha1nfo *s) {
+ uint8_t i;
+ uint32_t a,b,c,d,e,t;
+
+ a=s->state[0];
+ b=s->state[1];
+ c=s->state[2];
+ d=s->state[3];
+ e=s->state[4];
+ for (i=0; i<80; i++) {
+ if (i>=16) {
+ t = s->buffer[(i+13)&15] ^ s->buffer[(i+8)&15] ^ s->buffer[(i+2)&15] ^ s->buffer[i&15];
+ s->buffer[i&15] = sha1_rol32(t,1);
+ }
+ if (i<20) {
+ t = (d ^ (b & (c ^ d))) + SHA1_K0;
+ } else if (i<40) {
+ t = (b ^ c ^ d) + SHA1_K20;
+ } else if (i<60) {
+ t = ((b & c) | (d & (b | c))) + SHA1_K40;
+ } else {
+ t = (b ^ c ^ d) + SHA1_K60;
+ }
+ t+=sha1_rol32(a,5) + e + s->buffer[i&15];
+ e=d;
+ d=c;
+ c=sha1_rol32(b,30);
+ b=a;
+ a=t;
+ }
+ s->state[0] += a;
+ s->state[1] += b;
+ s->state[2] += c;
+ s->state[3] += d;
+ s->state[4] += e;
+}
+
+void sha1_addUncounted(sha1nfo *s, uint8_t data) {
+ uint8_t * const b = (uint8_t*) s->buffer;
+#ifdef SHA_BIG_ENDIAN
+ b[s->bufferOffset] = data;
+#else
+ b[s->bufferOffset ^ 3] = data;
+#endif
+ s->bufferOffset++;
+ if (s->bufferOffset == BLOCK_LENGTH) {
+ sha1_hashBlock(s);
+ s->bufferOffset = 0;
+ }
+}
+
+void sha1_writebyte(sha1nfo *s, uint8_t data) {
+ ++s->byteCount;
+ sha1_addUncounted(s, data);
+}
+
+void sha1_write(sha1nfo *s, const char *data, size_t len) {
+ for (;len--;) sha1_writebyte(s, (uint8_t) *data++);
+}
+
+void sha1_pad(sha1nfo *s) {
+ // Implement SHA-1 padding (fips180-2 ยง5.1.1)
+
+ // Pad with 0x80 followed by 0x00 until the end of the block
+ sha1_addUncounted(s, 0x80);
+ while (s->bufferOffset != 56) sha1_addUncounted(s, 0x00);
+
+ // Append length in the last 8 bytes
+ sha1_addUncounted(s, 0); // We're only using 32 bit lengths
+ sha1_addUncounted(s, 0); // But SHA-1 supports 64 bit lengths
+ sha1_addUncounted(s, 0); // So zero pad the top bits
+ sha1_addUncounted(s, s->byteCount >> 29); // Shifting to multiply by 8
+ sha1_addUncounted(s, s->byteCount >> 21); // as SHA-1 supports bitstreams as well as
+ sha1_addUncounted(s, s->byteCount >> 13); // byte.
+ sha1_addUncounted(s, s->byteCount >> 5);
+ sha1_addUncounted(s, s->byteCount << 3);
+}
+
+uint8_t* sha1_result(sha1nfo *s) {
+ // Pad to complete the last block
+ sha1_pad(s);
+
+#ifndef SHA_BIG_ENDIAN
+ // Swap byte order back
+ int i;
+ for (i=0; i<5; i++) {
+ s->state[i]=
+ (((s->state[i])<<24)& 0xff000000)
+ | (((s->state[i])<<8) & 0x00ff0000)
+ | (((s->state[i])>>8) & 0x0000ff00)
+ | (((s->state[i])>>24)& 0x000000ff);
+ }
+#endif
+
+ // Return pointer to hash (20 characters)
+ return (uint8_t*) s->state;
+}
+
+#define HMAC_IPAD 0x36
+#define HMAC_OPAD 0x5c
+
+void sha1_initHmac(sha1nfo *s, const uint8_t* key, int keyLength) {
+ uint8_t i;
+ memset(s->keyBuffer, 0, BLOCK_LENGTH);
+ if (keyLength > BLOCK_LENGTH) {
+ // Hash long keys
+ sha1_init(s);
+ for (;keyLength--;) sha1_writebyte(s, *key++);
+ memcpy(s->keyBuffer, sha1_result(s), HASH_LENGTH);
+ } else {
+ // Block length keys are used as is
+ memcpy(s->keyBuffer, key, keyLength);
+ }
+ // Start inner hash
+ sha1_init(s);
+ for (i=0; i<BLOCK_LENGTH; i++) {
+ sha1_writebyte(s, s->keyBuffer[i] ^ HMAC_IPAD);
+ }
+}
+
+uint8_t* sha1_resultHmac(sha1nfo *s) {
+ uint8_t i;
+ // Complete inner hash
+ memcpy(s->innerHash,sha1_result(s),HASH_LENGTH);
+ // Calculate outer hash
+ sha1_init(s);
+ for (i=0; i<BLOCK_LENGTH; i++) sha1_writebyte(s, s->keyBuffer[i] ^ HMAC_OPAD);
+ for (i=0; i<HASH_LENGTH; i++) sha1_writebyte(s, s->innerHash[i]);
+ return sha1_result(s);
+}
+
+/* self-test */
+
+#if SHA1TEST
+#include <stdio.h>
+
+uint8_t hmacKey1[]={
+ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
+ 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,
+ 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,
+ 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f
+};
+uint8_t hmacKey2[]={
+ 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+ 0x40,0x41,0x42,0x43
+};
+uint8_t hmacKey3[]={
+ 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f,
+ 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,
+ 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f,
+ 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f,
+ 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f,
+ 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf,
+ 0xb0,0xb1,0xb2,0xb3
+};
+uint8_t hmacKey4[]={
+ 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f,
+ 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f,
+ 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f,
+ 0xa0
+};
+
+void printHash(uint8_t* hash) {
+ int i;
+ for (i=0; i<20; i++) {
+ printf("%02x", hash[i]);
+ }
+ printf("\n");
+}
+
+
+int main (int argc, char **argv) {
+ uint32_t a;
+ sha1nfo s;
+
+ // SHA tests
+ printf("Test: FIPS 180-2 C.1 and RFC3174 7.3 TEST1\n");
+ printf("Expect:a9993e364706816aba3e25717850c26c9cd0d89d\n");
+ printf("Result:");
+ sha1_init(&s);
+ sha1_write(&s, "abc", 3);
+ printHash(sha1_result(&s));
+ printf("\n\n");
+
+ printf("Test: FIPS 180-2 C.2 and RFC3174 7.3 TEST2\n");
+ printf("Expect:84983e441c3bd26ebaae4aa1f95129e5e54670f1\n");
+ printf("Result:");
+ sha1_init(&s);
+ sha1_write(&s, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56);
+ printHash(sha1_result(&s));
+ printf("\n\n");
+
+ printf("Test: RFC3174 7.3 TEST4\n");
+ printf("Expect:dea356a2cddd90c7a7ecedc5ebb563934f460452\n");
+ printf("Result:");
+ sha1_init(&s);
+ for (a=0; a<80; a++) sha1_write(&s, "01234567", 8);
+ printHash(sha1_result(&s));
+ printf("\n\n");
+
+ // HMAC tests
+ printf("Test: FIPS 198a A.1\n");
+ printf("Expect:4f4ca3d5d68ba7cc0a1208c9c61e9c5da0403c0a\n");
+ printf("Result:");
+ sha1_initHmac(&s, hmacKey1, 64);
+ sha1_write(&s, "Sample #1",9);
+ printHash(sha1_resultHmac(&s));
+ printf("\n\n");
+
+ printf("Test: FIPS 198a A.2\n");
+ printf("Expect:0922d3405faa3d194f82a45830737d5cc6c75d24\n");
+ printf("Result:");
+ sha1_initHmac(&s, hmacKey2, 20);
+ sha1_write(&s, "Sample #2", 9);
+ printHash(sha1_resultHmac(&s));
+ printf("\n\n");
+
+ printf("Test: FIPS 198a A.3\n");
+ printf("Expect:bcf41eab8bb2d802f3d05caf7cb092ecf8d1a3aa\n");
+ printf("Result:");
+ sha1_initHmac(&s, hmacKey3,100);
+ sha1_write(&s, "Sample #3", 9);
+ printHash(sha1_resultHmac(&s));
+ printf("\n\n");
+
+ printf("Test: FIPS 198a A.4\n");
+ printf("Expect:9ea886efe268dbecce420c7524df32e0751a2a26\n");
+ printf("Result:");
+ sha1_initHmac(&s, hmacKey4,49);
+ sha1_write(&s, "Sample #4", 9);
+ printHash(sha1_resultHmac(&s));
+ printf("\n\n");
+
+ // Long tests
+ printf("Test: FIPS 180-2 C.3 and RFC3174 7.3 TEST3\n");
+ printf("Expect:34aa973cd4c4daa4f61eeb2bdbad27316534016f\n");
+ printf("Result:");
+ sha1_init(&s);
+ for (a=0; a<1000000; a++) sha1_writebyte(&s, 'a');
+ printHash(sha1_result(&s));
+
+ return 0;
+}
+#endif /* self-test */
diff --git a/src/xmalloc.c b/src/xmalloc.c
index f831e13..bd2136f 100644
--- a/src/xmalloc.c
+++ b/src/xmalloc.c
@@ -57,4 +57,7 @@ char *xstrdup (const char *s) {
return (char*) ptr;
}
+void xfree(void *ptr) {
+ return free(ptr);
+}
// vi: sts=2 sw=2 ts=2
diff --git a/src/xmalloc.h b/src/xmalloc.h
index 7ec9b61..6471371 100644
--- a/src/xmalloc.h
+++ b/src/xmalloc.h
@@ -6,5 +6,6 @@ void *xmalloc (size_t size);
void *xcalloc (size_t nmemb, size_t size);
void *xrealloc (void *ptr, size_t size);
char *xstrdup (const char *s);
+void xfree(void *ptr);
#endif