Unify coding style
@sjaeckel integrated clang-format with formal coding style. Run his script and commit changes. There are pros and cons of this commit. Mixed coding style is a "broken window". A good single style simplifies reading and writing code. On the other hand, this is a big change which will lead to conflicts.
This commit is contained in:
221
src/sasl.c
221
src/sasl.c
@@ -29,16 +29,16 @@
|
||||
/* strtok_s() has appeared in visual studio 2005.
|
||||
Use own implementation for older versions. */
|
||||
#ifdef _MSC_VER
|
||||
# if (_MSC_VER >= 1400)
|
||||
# define strtok_r strtok_s
|
||||
# else
|
||||
# define strtok_r xmpp_strtok_r
|
||||
# endif
|
||||
#if (_MSC_VER >= 1400)
|
||||
#define strtok_r strtok_s
|
||||
#else
|
||||
#define strtok_r xmpp_strtok_r
|
||||
#endif
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
|
||||
/** generate authentication string for the SASL PLAIN mechanism */
|
||||
char *sasl_plain(xmpp_ctx_t *ctx, const char *authid, const char *password) {
|
||||
char *sasl_plain(xmpp_ctx_t *ctx, const char *authid, const char *password)
|
||||
{
|
||||
size_t idlen, passlen;
|
||||
size_t msglen;
|
||||
char *result = NULL;
|
||||
@@ -52,12 +52,12 @@ char *sasl_plain(xmpp_ctx_t *ctx, const char *authid, const char *password) {
|
||||
msglen = 2 + idlen + passlen;
|
||||
msg = xmpp_alloc(ctx, msglen);
|
||||
if (msg != NULL) {
|
||||
msg[0] = '\0';
|
||||
memcpy(msg+1, authid, idlen);
|
||||
msg[1+idlen] = '\0';
|
||||
memcpy(msg+1+idlen+1, password, passlen);
|
||||
result = xmpp_base64_encode(ctx, (unsigned char *)msg, msglen);
|
||||
xmpp_free(ctx, msg);
|
||||
msg[0] = '\0';
|
||||
memcpy(msg + 1, authid, idlen);
|
||||
msg[1 + idlen] = '\0';
|
||||
memcpy(msg + 1 + idlen + 1, password, passlen);
|
||||
result = xmpp_base64_encode(ctx, (unsigned char *)msg, msglen);
|
||||
xmpp_free(ctx, msg);
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -72,8 +72,8 @@ static char *_make_string(xmpp_ctx_t *ctx, const char *s, const unsigned len)
|
||||
|
||||
result = xmpp_alloc(ctx, len + 1);
|
||||
if (result != NULL) {
|
||||
memcpy(result, s, len);
|
||||
result[len] = '\0';
|
||||
memcpy(result, s, len);
|
||||
result[len] = '\0';
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -86,10 +86,10 @@ static char *_make_quoted(xmpp_ctx_t *ctx, const char *s)
|
||||
|
||||
result = xmpp_alloc(ctx, len + 3);
|
||||
if (result != NULL) {
|
||||
result[0] = '"';
|
||||
memcpy(result+1, s, len);
|
||||
result[len+1] = '"';
|
||||
result[len+2] = '\0';
|
||||
result[0] = '"';
|
||||
memcpy(result + 1, s, len);
|
||||
result[len + 1] = '"';
|
||||
result[len + 2] = '\0';
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -104,51 +104,56 @@ static hash_t *_parse_digest_challenge(xmpp_ctx_t *ctx, const char *msg)
|
||||
|
||||
text = (unsigned char *)xmpp_base64_decode_str(ctx, msg, strlen(msg));
|
||||
if (text == NULL) {
|
||||
xmpp_error(ctx, "SASL", "couldn't Base64 decode challenge!");
|
||||
return NULL;
|
||||
xmpp_error(ctx, "SASL", "couldn't Base64 decode challenge!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
result = hash_new(ctx, 10, xmpp_free);
|
||||
if (result != NULL) {
|
||||
s = text;
|
||||
while (*s != '\0') {
|
||||
/* skip any leading commas and spaces */
|
||||
while ((*s == ',') || (*s == ' ')) s++;
|
||||
/* accumulate a key ending at '=' */
|
||||
t = s;
|
||||
while ((*t != '=') && (*t != '\0')) t++;
|
||||
if (*t == '\0') break; /* bad string */
|
||||
key = _make_string(ctx, (char *)s, (t-s));
|
||||
if (key == NULL) break;
|
||||
s = text;
|
||||
while (*s != '\0') {
|
||||
/* skip any leading commas and spaces */
|
||||
while ((*s == ',') || (*s == ' '))
|
||||
s++;
|
||||
/* accumulate a key ending at '=' */
|
||||
t = s;
|
||||
while ((*t != '=') && (*t != '\0'))
|
||||
t++;
|
||||
if (*t == '\0')
|
||||
break; /* bad string */
|
||||
key = _make_string(ctx, (char *)s, (t - s));
|
||||
if (key == NULL)
|
||||
break;
|
||||
/* advance our start pointer past the key */
|
||||
s = t + 1;
|
||||
t = s;
|
||||
/* if we see quotes, grab the string in between */
|
||||
if ((*s == '\'') || (*s == '"')) {
|
||||
t++;
|
||||
while ((*t != *s) && (*t != '\0'))
|
||||
t++;
|
||||
value = _make_string(ctx, (char *)s+1, (t-s-1));
|
||||
if (*t == *s) {
|
||||
s = t + 1;
|
||||
} else {
|
||||
s = t;
|
||||
}
|
||||
/* otherwise, accumulate a value ending in ',' or '\0' */
|
||||
} else {
|
||||
while ((*t != ',') && (*t != '\0')) t++;
|
||||
value = _make_string(ctx, (char *)s, (t-s));
|
||||
s = t;
|
||||
}
|
||||
if (value == NULL) {
|
||||
xmpp_free(ctx, key);
|
||||
break;
|
||||
}
|
||||
/* TODO: check for collisions per spec */
|
||||
hash_add(result, key, value);
|
||||
/* hash table now owns the value, free the key */
|
||||
xmpp_free(ctx, key);
|
||||
}
|
||||
s = t + 1;
|
||||
t = s;
|
||||
/* if we see quotes, grab the string in between */
|
||||
if ((*s == '\'') || (*s == '"')) {
|
||||
t++;
|
||||
while ((*t != *s) && (*t != '\0'))
|
||||
t++;
|
||||
value = _make_string(ctx, (char *)s + 1, (t - s - 1));
|
||||
if (*t == *s) {
|
||||
s = t + 1;
|
||||
} else {
|
||||
s = t;
|
||||
}
|
||||
/* otherwise, accumulate a value ending in ',' or '\0' */
|
||||
} else {
|
||||
while ((*t != ',') && (*t != '\0'))
|
||||
t++;
|
||||
value = _make_string(ctx, (char *)s, (t - s));
|
||||
s = t;
|
||||
}
|
||||
if (value == NULL) {
|
||||
xmpp_free(ctx, key);
|
||||
break;
|
||||
}
|
||||
/* TODO: check for collisions per spec */
|
||||
hash_add(result, key, value);
|
||||
/* hash table now owns the value, free the key */
|
||||
xmpp_free(ctx, key);
|
||||
}
|
||||
}
|
||||
xmpp_free(ctx, text);
|
||||
|
||||
@@ -162,63 +167,75 @@ static void _digest_to_hex(const char *digest, char *hex)
|
||||
const char hexdigit[] = "0123456789abcdef";
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
*hex++ = hexdigit[ (digest[i] >> 4) & 0x0F ];
|
||||
*hex++ = hexdigit[ digest[i] & 0x0F ];
|
||||
*hex++ = hexdigit[(digest[i] >> 4) & 0x0F];
|
||||
*hex++ = hexdigit[digest[i] & 0x0F];
|
||||
}
|
||||
}
|
||||
|
||||
/** append 'key="value"' to a buffer, growing as necessary */
|
||||
static char *_add_key(xmpp_ctx_t *ctx, hash_t *table, const char *key,
|
||||
char *buf, int *len, int quote)
|
||||
static char *_add_key(xmpp_ctx_t *ctx,
|
||||
hash_t *table,
|
||||
const char *key,
|
||||
char *buf,
|
||||
int *len,
|
||||
int quote)
|
||||
{
|
||||
int olen,nlen;
|
||||
int olen, nlen;
|
||||
int keylen, valuelen;
|
||||
const char *value, *qvalue;
|
||||
char *c;
|
||||
|
||||
/* allocate a zero-length string if necessary */
|
||||
if (buf == NULL) {
|
||||
buf = xmpp_alloc(ctx, 1);
|
||||
buf[0] = '\0';
|
||||
buf = xmpp_alloc(ctx, 1);
|
||||
buf[0] = '\0';
|
||||
}
|
||||
if (buf == NULL) return NULL;
|
||||
if (buf == NULL)
|
||||
return NULL;
|
||||
|
||||
/* get current string length */
|
||||
olen = strlen(buf);
|
||||
value = hash_get(table, key);
|
||||
if (value == NULL) {
|
||||
xmpp_error(ctx, "SASL", "couldn't retrieve value for '%s'", key);
|
||||
value = "";
|
||||
xmpp_error(ctx, "SASL", "couldn't retrieve value for '%s'", key);
|
||||
value = "";
|
||||
}
|
||||
if (quote) {
|
||||
qvalue = _make_quoted(ctx, value);
|
||||
qvalue = _make_quoted(ctx, value);
|
||||
} else {
|
||||
qvalue = value;
|
||||
qvalue = value;
|
||||
}
|
||||
/* added length is key + '=' + value */
|
||||
/* (+ ',' if we're not the first entry */
|
||||
keylen = strlen(key);
|
||||
valuelen = strlen(qvalue);
|
||||
nlen = (olen ? 1 : 0) + keylen + 1 + valuelen + 1;
|
||||
buf = xmpp_realloc(ctx, buf, olen+nlen);
|
||||
buf = xmpp_realloc(ctx, buf, olen + nlen);
|
||||
|
||||
if (buf != NULL) {
|
||||
c = buf + olen;
|
||||
if (olen) *c++ = ',';
|
||||
memcpy(c, key, keylen); c += keylen;
|
||||
*c++ = '=';
|
||||
memcpy(c, qvalue, valuelen); c += valuelen;
|
||||
*c++ = '\0';
|
||||
c = buf + olen;
|
||||
if (olen)
|
||||
*c++ = ',';
|
||||
memcpy(c, key, keylen);
|
||||
c += keylen;
|
||||
*c++ = '=';
|
||||
memcpy(c, qvalue, valuelen);
|
||||
c += valuelen;
|
||||
*c++ = '\0';
|
||||
}
|
||||
|
||||
if (quote) xmpp_free(ctx, (char *)qvalue);
|
||||
if (quote)
|
||||
xmpp_free(ctx, (char *)qvalue);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
/** generate auth response string for the SASL DIGEST-MD5 mechanism */
|
||||
char *sasl_digest_md5(xmpp_ctx_t *ctx, const char *challenge,
|
||||
const char *jid, const char *password) {
|
||||
char *sasl_digest_md5(xmpp_ctx_t *ctx,
|
||||
const char *challenge,
|
||||
const char *jid,
|
||||
const char *password)
|
||||
{
|
||||
hash_t *table;
|
||||
char *result = NULL;
|
||||
char *node, *domain, *realm;
|
||||
@@ -231,21 +248,21 @@ char *sasl_digest_md5(xmpp_ctx_t *ctx, const char *challenge,
|
||||
char cnonce[13];
|
||||
|
||||
/* our digest response is
|
||||
Hex( KD( HEX(MD5(A1)),
|
||||
nonce ':' nc ':' cnonce ':' qop ':' HEX(MD5(A2))
|
||||
))
|
||||
Hex( KD( HEX(MD5(A1)),
|
||||
nonce ':' nc ':' cnonce ':' qop ':' HEX(MD5(A2))
|
||||
))
|
||||
|
||||
where KD(k, s) = MD5(k ':' s),
|
||||
A1 = MD5( node ':' realm ':' password ) ':' nonce ':' cnonce
|
||||
A2 = "AUTHENTICATE" ':' "xmpp/" domain
|
||||
A1 = MD5( node ':' realm ':' password ) ':' nonce ':' cnonce
|
||||
A2 = "AUTHENTICATE" ':' "xmpp/" domain
|
||||
|
||||
If there is an authzid it is ':'-appended to A1 */
|
||||
|
||||
/* parse the challenge */
|
||||
table = _parse_digest_challenge(ctx, challenge);
|
||||
if (table == NULL) {
|
||||
xmpp_error(ctx, "SASL", "couldn't parse digest challenge");
|
||||
return NULL;
|
||||
xmpp_error(ctx, "SASL", "couldn't parse digest challenge");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
node = xmpp_jid_node(ctx, jid);
|
||||
@@ -255,8 +272,8 @@ char *sasl_digest_md5(xmpp_ctx_t *ctx, const char *challenge,
|
||||
server */
|
||||
realm = hash_get(table, "realm");
|
||||
if (realm == NULL || strlen(realm) == 0) {
|
||||
hash_add(table, "realm", xmpp_strdup(ctx, domain));
|
||||
realm = hash_get(table, "realm");
|
||||
hash_add(table, "realm", xmpp_strdup(ctx, domain));
|
||||
realm = hash_get(table, "realm");
|
||||
}
|
||||
|
||||
/* add our response fields */
|
||||
@@ -268,8 +285,8 @@ char *sasl_digest_md5(xmpp_ctx_t *ctx, const char *challenge,
|
||||
hash_add(table, "qop", xmpp_strdup(ctx, "auth"));
|
||||
value = xmpp_alloc(ctx, 5 + strlen(domain) + 1);
|
||||
memcpy(value, "xmpp/", 5);
|
||||
memcpy(value+5, domain, strlen(domain));
|
||||
value[5+strlen(domain)] = '\0';
|
||||
memcpy(value + 5, domain, strlen(domain));
|
||||
value[5 + strlen(domain)] = '\0';
|
||||
hash_add(table, "digest-uri", value);
|
||||
|
||||
/* generate response */
|
||||
@@ -304,8 +321,8 @@ char *sasl_digest_md5(xmpp_ctx_t *ctx, const char *challenge,
|
||||
value = hash_get(table, "digest-uri");
|
||||
MD5Update(&MD5, (unsigned char *)value, strlen(value));
|
||||
if (strcmp(hash_get(table, "qop"), "auth") != 0) {
|
||||
MD5Update(&MD5, (unsigned char *)":00000000000000000000000000000000",
|
||||
33);
|
||||
MD5Update(&MD5, (unsigned char *)":00000000000000000000000000000000",
|
||||
33);
|
||||
}
|
||||
MD5Final(digest, &MD5);
|
||||
|
||||
@@ -332,7 +349,7 @@ char *sasl_digest_md5(xmpp_ctx_t *ctx, const char *challenge,
|
||||
MD5Update(&MD5, (unsigned char *)hex, 32);
|
||||
MD5Final(digest, &MD5);
|
||||
|
||||
response = xmpp_alloc(ctx, 32+1);
|
||||
response = xmpp_alloc(ctx, 32 + 1);
|
||||
_digest_to_hex((char *)digest, hex);
|
||||
memcpy(response, hex, 32);
|
||||
response[32] = '\0';
|
||||
@@ -363,8 +380,10 @@ char *sasl_digest_md5(xmpp_ctx_t *ctx, const char *challenge,
|
||||
}
|
||||
|
||||
/** generate auth response string for the SASL SCRAM-SHA-1 mechanism */
|
||||
char *sasl_scram_sha1(xmpp_ctx_t *ctx, const char *challenge,
|
||||
const char *first_bare, const char *jid,
|
||||
char *sasl_scram_sha1(xmpp_ctx_t *ctx,
|
||||
const char *challenge,
|
||||
const char *first_bare,
|
||||
const char *jid,
|
||||
const char *password)
|
||||
{
|
||||
uint8_t key[SHA1_DIGEST_SIZE];
|
||||
@@ -430,8 +449,8 @@ char *sasl_scram_sha1(xmpp_ctx_t *ctx, const char *challenge,
|
||||
xmpp_snprintf(auth, auth_len, "%s,%s,%s", first_bare + 3, challenge,
|
||||
response);
|
||||
|
||||
SCRAM_SHA1_ClientKey((uint8_t *)password, strlen(password),
|
||||
(uint8_t *)sval, sval_len, (uint32_t)ival, key);
|
||||
SCRAM_SHA1_ClientKey((uint8_t *)password, strlen(password), (uint8_t *)sval,
|
||||
sval_len, (uint32_t)ival, key);
|
||||
SCRAM_SHA1_ClientSignature(key, (uint8_t *)auth, strlen(auth), sign);
|
||||
for (j = 0; j < SHA1_DIGEST_SIZE; j++) {
|
||||
sign[j] ^= key[j];
|
||||
@@ -450,8 +469,8 @@ char *sasl_scram_sha1(xmpp_ctx_t *ctx, const char *challenge,
|
||||
strcat(response, sign_b64);
|
||||
xmpp_free(ctx, sign_b64);
|
||||
|
||||
response_b64 = xmpp_base64_encode(ctx, (unsigned char *)response,
|
||||
strlen(response));
|
||||
response_b64 =
|
||||
xmpp_base64_encode(ctx, (unsigned char *)response, strlen(response));
|
||||
if (!response_b64) {
|
||||
goto out_response;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user