<commit_before>/*** Copyright (c), The Regents of the University of California            ***
 *** For more information please refer to files in the COPYRIGHT directory ***/
/*
  These routines are used to implement the OS level authentication scheme.


  Returns codes of 0 indicate success, others are iRODS error codes.
*/

#include <stdlib.h>
#include <stdio.h>
#include <limits>
#ifndef windows_platform
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#endif

#include "rods.hpp"
#include "rcGlobalExtern.hpp"
#include "authenticate.hpp"
extern "C" {

    int
    osauthVerifyResponse( char *challenge, char *username, char *response ) {
#if defined(OS_AUTH)
        static char fname[] = "osauthVerifyResponse";
        char authenticator[16]; /* MD5 hash */
        char md5buffer[CHALLENGE_LEN + MAX_PASSWORD_LEN + 2];
        char md5digest[RESPONSE_LEN + 2];
        int uid, status, i;
        char *keybuf = NULL;
        int key_len;
        MD5_CTX ctx;

        uid = osauthGetUid( username );
        if ( uid == -1 ) {
            return SYS_USER_RETRIEVE_ERR;
        }

        /* read the key from the key file */
        if ( ( status = osauthGetKey( &keybuf, &key_len ) ) ) {
            rodsLogError( LOG_ERROR, status,
                          "%s: error retrieving key.", fname );
            return status;
        }

        /* generate the authenticator */
        status = osauthGenerateAuthenticator( username, uid, challenge,
                                              keybuf, key_len,
                                              authenticator, 16 );
        if ( status ) {
            rodsLog( LOG_ERROR,
                     "%s: could not generate the authenticator", fname );
            free( keybuf );
            return status;
        }
        free( keybuf );

        /* now append this hash with the challenge, and
           take the md5 sum of that */
        memset( md5buffer, 0, sizeof( md5buffer ) );
        memset( md5digest, 0, sizeof( md5digest ) );
        memcpy( md5buffer, challenge, CHALLENGE_LEN );
        memcpy( md5buffer + CHALLENGE_LEN, authenticator, 16 );
        MD5Init( &ctx );
        MD5Update( &ctx, ( unsigned char* )md5buffer, CHALLENGE_LEN + MAX_PASSWORD_LEN );
        MD5Final( ( unsigned char* )md5digest, &ctx );
        for ( i = 0; i < RESPONSE_LEN; i++ ) {
            /* make sure 'string' doesn't end early
               (this matches client digest generation). */
            if ( md5digest[i] == '\0' ) {
                md5digest[i]++;
            }
        }

        /* compare the calculated digest to the client response */
        for ( i = 0; i < RESPONSE_LEN; i++ ) {
            if ( response[i] != md5digest[i] ) {
                rodsLog( LOG_ERROR, "%s: calculated digest doesn't match client response",
                         fname );
                return CAT_INVALID_AUTHENTICATION;
            }
        }

        return 0;

#else /* defined OS_AUTH */
        if ( ProcessType == CLIENT_PT ) {
            return OSAUTH_NOT_BUILT_INTO_CLIENT;
        }
        else {
            return OSAUTH_NOT_BUILT_INTO_SERVER;
        }
#endif
    }

    /*
     * osauthGenerateAuthenticator - this functions creates
     * an authenticator from the passed in parameters. The
     * parameters are concatenated together, and then an
     * md5 hash is generated and provided in the output
     * parameter. Returns 0 on success, error code on error.
     */
    int
    osauthGenerateAuthenticator( char *username, int uid,
                                 char *challenge, char *key, int key_len,
                                 char *authenticator, int authenticator_len ) {
#if defined(OS_AUTH)
        static char fname[] = "osauthGenerateAuthenticator";
        char *buffer, *bufp;
        int buflen;
        char md5digest[16];
        MD5_CTX ctx;

        if ( authenticator == NULL ||
                authenticator_len < 16 ) {
            return USER_INPUT_OPTION_ERR;
        }

        /* calculate buffer size and allocate */
        buflen = username ? strlen( username ) : 0;
        buflen += sizeof( uid ) + CHALLENGE_LEN + key_len;
        buffer = ( char* )malloc( buflen );
        if ( buffer == NULL ) {
            rodsLog( LOG_ERROR,
                     "%s: could not allocate memory buffer. errno = %d",
                     fname, errno );
            return SYS_MALLOC_ERR;
        }

        /* concatenate the input parameters */
        bufp = buffer;
        if ( username && strlen( username ) ) {
            memcpy( bufp, username, strlen( username ) );
            bufp += strlen( username );
        }
#if defined(OS_AUTH_NO_UID)
        uid = 0;
#endif
        memcpy( bufp, &uid, sizeof( uid ) );
        bufp += sizeof( uid );
        if ( challenge ) {
            memcpy( bufp, challenge, CHALLENGE_LEN );
            bufp += CHALLENGE_LEN;
        }
        if ( key ) {
            memcpy( bufp, key, key_len );
        }

        /* generate an MD5 hash of the buffer, and copy it
           to the output parameter authenticator */
        MD5Init( &ctx );
        MD5Update( &ctx, ( unsigned char* )buffer, buflen );
        MD5Final( ( unsigned char* )md5digest, &ctx );
        memcpy( authenticator, md5digest, 16 );

        return 0;

#else /* defined OS_AUTH */
        if ( ProcessType == CLIENT_PT ) {<commit_msg>[#2212] CID26257:<commit_after>/*** Copyright (c), The Regents of the University of California            ***
 *** For more information please refer to files in the COPYRIGHT directory ***/
/*
  These routines are used to implement the OS level authentication scheme.


  Returns codes of 0 indicate success, others are iRODS error codes.
*/

#include <stdlib.h>
#include <stdio.h>
#include <limits>
#ifndef windows_platform
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#endif

#include "rods.hpp"
#include "rcGlobalExtern.hpp"
#include "authenticate.hpp"
extern "C" {

    int
    osauthVerifyResponse( char *challenge, char *username, char *response ) {
#if defined(OS_AUTH)
        static char fname[] = "osauthVerifyResponse";
        char authenticator[16]; /* MD5 hash */
        char md5buffer[CHALLENGE_LEN + MAX_PASSWORD_LEN + 2];
        char md5digest[RESPONSE_LEN + 2];
        int uid, status, i;
        char *keybuf = NULL;
        int key_len;
        MD5_CTX ctx;

        uid = osauthGetUid( username );
        if ( uid == -1 ) {
            return SYS_USER_RETRIEVE_ERR;
        }

        /* read the key from the key file */
        if ( ( status = osauthGetKey( &keybuf, &key_len ) ) ) {
            rodsLogError( LOG_ERROR, status,
                          "%s: error retrieving key.", fname );
            return status;
        }

        /* generate the authenticator */
        status = osauthGenerateAuthenticator( username, uid, challenge,
                                              keybuf, key_len,
                                              authenticator, 16 );
        if ( status ) {
            rodsLog( LOG_ERROR,
                     "%s: could not generate the authenticator", fname );
            free( keybuf );
            return status;
        }
        free( keybuf );

        /* now append this hash with the challenge, and
           take the md5 sum of that */
        memset( md5buffer, 0, sizeof( md5buffer ) );
        memset( md5digest, 0, sizeof( md5digest ) );
        memcpy( md5buffer, challenge, CHALLENGE_LEN );
        memcpy( md5buffer + CHALLENGE_LEN, authenticator, 16 );
        MD5Init( &ctx );
        MD5Update( &ctx, ( unsigned char* )md5buffer, CHALLENGE_LEN + MAX_PASSWORD_LEN );
        MD5Final( ( unsigned char* )md5digest, &ctx );
        for ( i = 0; i < RESPONSE_LEN; i++ ) {
            /* make sure 'string' doesn't end early
               (this matches client digest generation). */
            if ( md5digest[i] == '\0' ) {
                md5digest[i]++;
            }
        }

        /* compare the calculated digest to the client response */
        for ( i = 0; i < RESPONSE_LEN; i++ ) {
            if ( response[i] != md5digest[i] ) {
                rodsLog( LOG_ERROR, "%s: calculated digest doesn't match client response",
                         fname );
                return CAT_INVALID_AUTHENTICATION;
            }
        }

        return 0;

#else /* defined OS_AUTH */
        if ( ProcessType == CLIENT_PT ) {
            return OSAUTH_NOT_BUILT_INTO_CLIENT;
        }
        else {
            return OSAUTH_NOT_BUILT_INTO_SERVER;
        }
#endif
    }

    /*
     * osauthGenerateAuthenticator - this functions creates
     * an authenticator from the passed in parameters. The
     * parameters are concatenated together, and then an
     * md5 hash is generated and provided in the output
     * parameter. Returns 0 on success, error code on error.
     */
    int
    osauthGenerateAuthenticator( char *username, int uid,
                                 char *challenge, char *key, int key_len,
                                 char *authenticator, int authenticator_len ) {
#if defined(OS_AUTH)
        static char fname[] = "osauthGenerateAuthenticator";
        char *buffer, *bufp;
        int buflen;
        char md5digest[16];
        MD5_CTX ctx;

        if ( authenticator == NULL ||
                authenticator_len < 16 ) {
            return USER_INPUT_OPTION_ERR;
        }

        /* calculate buffer size and allocate */
        buflen = username ? strlen( username ) : 0;
        buflen += sizeof( uid ) + CHALLENGE_LEN + key_len;
        buffer = ( char* )malloc( buflen );
        if ( buffer == NULL ) {
            rodsLog( LOG_ERROR,
                     "%s: could not allocate memory buffer. errno = %d",
                     fname, errno );
            return SYS_MALLOC_ERR;
        }

        /* concatenate the input parameters */
        bufp = buffer;
        if ( username && strlen( username ) ) {
            memcpy( bufp, username, strlen( username ) );
            bufp += strlen( username );
        }
#if defined(OS_AUTH_NO_UID)
        uid = 0;
#endif
        memcpy( bufp, &uid, sizeof( uid ) );
        bufp += sizeof( uid );
        if ( challenge ) {
            memcpy( bufp, challenge, CHALLENGE_LEN );
            bufp += CHALLENGE_LEN;
        }
        if ( key ) {
            memcpy( bufp, key, key_len );
        }

        /* generate an MD5 hash of the buffer, and copy it
           to the output parameter authenticator */
        MD5Init( &ctx );
        MD5Update( &ctx, ( unsigned char* )buffer, buflen );
        MD5Final( ( unsigned char* )md5digest, &ctx );
        memcpy( authenticator, md5digest, 16 );

        free( buffer );
        return 0;

#else /* defined OS_AUTH */
        if ( ProcessType == CLIENT_PT ) {
{'fraction_non_alphanumeric': 0.09972375690607735, 'fraction_numerical': 0.010773480662983425, 'mean_word_length': 1.7685444812643385, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 12, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '335243', 'n_tokens_mistral': 3215, 'n_tokens_neox': 3072, 'n_words': 943}