Example #1
0
int
rsAuthResponse (rsComm_t *rsComm, authResponseInp_t *authResponseInp)
{
   int status;
   char *bufp;
   authCheckInp_t authCheckInp;
   authCheckOut_t *authCheckOut = NULL;
   rodsServerHost_t *rodsServerHost;

   char digest[RESPONSE_LEN+2];
   char md5Buf[CHALLENGE_LEN+MAX_PASSWORD_LEN+2];
   char serverId[MAX_PASSWORD_LEN+2];
   MD5_CTX context;

   bufp = _rsAuthRequestGetChallenge();

   /* need to do NoLogin because it could get into inf loop for cross 
    * zone auth */

   status = getAndConnRcatHostNoLogin (rsComm, SLAVE_RCAT, 
    rsComm->proxyUser.rodsZone, &rodsServerHost);
   if (status < 0) {
      return(status);
   }

   memset (&authCheckInp, 0, sizeof (authCheckInp)); 
   authCheckInp.challenge = bufp;
   authCheckInp.response = authResponseInp->response;
   authCheckInp.username = authResponseInp->username;

   if (rodsServerHost->localFlag == LOCAL_HOST) {
      status = rsAuthCheck (rsComm, &authCheckInp, &authCheckOut);
   } else {
      status = rcAuthCheck (rodsServerHost->conn, &authCheckInp, &authCheckOut);
      /* not likely we need this connection again */
      rcDisconnect(rodsServerHost->conn);
      rodsServerHost->conn = NULL;
   }
   if (status < 0) {
      rodsLog (LOG_NOTICE,
            "rsAuthResponse: rxAuthCheck failed, status = %d", status);
      return (status);
   }

   if (rodsServerHost->localFlag != LOCAL_HOST) {
      if (authCheckOut->serverResponse == NULL) {
	 rodsLog(LOG_NOTICE, "Warning, cannot authenticate remote server, no serverResponse field");
	 if (requireServerAuth) {
	    rodsLog(LOG_NOTICE, "Authentication disallowed, no serverResponse field");
	    return(REMOTE_SERVER_AUTH_NOT_PROVIDED);
	 }
      }
      else {
	 char *cp;
	 int OK, len, i;
	 if (*authCheckOut->serverResponse == '\0') {
	    rodsLog(LOG_NOTICE, "Warning, cannot authenticate remote server, serverResponse field is empty");
	    if (requireServerAuth) { 
	       rodsLog(LOG_NOTICE, "Authentication disallowed, empty serverResponse");
	       return(REMOTE_SERVER_AUTH_EMPTY);  
	    }
	 }
	 else {
	    char username2[NAME_LEN+2];
	    char userZone[NAME_LEN+2];
	    memset(md5Buf, 0, sizeof(md5Buf));
	    strncpy(md5Buf, authCheckInp.challenge, CHALLENGE_LEN);
	    parseUserName(authResponseInp->username, username2, userZone);
	    getZoneServerId(userZone, serverId);
	    len = strlen(serverId);
	    if (len <= 0) {
	       rodsLog (LOG_NOTICE, "rsAuthResponse: Warning, cannot authenticate the remote server, no RemoteZoneSID defined in server.config", status);
	       if (requireServerAuth) {
		  rodsLog(LOG_NOTICE, "Authentication disallowed, no RemoteZoneSID defined");
		  return(REMOTE_SERVER_SID_NOT_DEFINED);  
	       }
	    }
	    else { 
	       strncpy(md5Buf+CHALLENGE_LEN, serverId, len);
	       MD5Init (&context);
	       MD5Update (&context, (unsigned char*)md5Buf, 
			  CHALLENGE_LEN+MAX_PASSWORD_LEN);
	       MD5Final ((unsigned char*)digest, &context);
	       for (i=0;i<RESPONSE_LEN;i++) {
		  if (digest[i]=='\0') digest[i]++;  /* make sure 'string' doesn't
							end early*/
	       }
	       cp = authCheckOut->serverResponse;
	       OK=1;
	       for (i=0;i<RESPONSE_LEN;i++) {
		  if (*cp++ != digest[i]) OK=0;
	       }
	       rodsLog(LOG_DEBUG, "serverResponse is OK/Not: %d", OK);
	       if (OK==0) {
		  rodsLog(LOG_NOTICE, "Server response incorrect, authentication disallowed");
		  return(REMOTE_SERVER_AUTHENTICATION_FAILURE);
	       }
	    }
	 }
      }
   }

   /* Set the clientUser zone if it is null. */
   if (strlen(rsComm->clientUser.rodsZone)==0) {
      zoneInfo_t *tmpZoneInfo;
      status = getLocalZoneInfo (&tmpZoneInfo);
      if (status < 0) {
	 free (authCheckOut);
	 return status;
      }
      strncpy(rsComm->clientUser.rodsZone,
	      tmpZoneInfo->zoneName, NAME_LEN);
   }


   /* have to modify privLevel if the icat is a foreign icat because
    * a local user in a foreign zone is not a local user in this zone
    * and vice vera for a remote user
    */
   if (rodsServerHost->rcatEnabled == REMOTE_ICAT) {
      /* proxy is easy because rodsServerHost is based on proxy user */
        if (authCheckOut->privLevel == LOCAL_PRIV_USER_AUTH)
            authCheckOut->privLevel = REMOTE_PRIV_USER_AUTH;
        else if (authCheckOut->privLevel == LOCAL_PRIV_USER_AUTH)
            authCheckOut->privLevel = REMOTE_PRIV_USER_AUTH;

	/* adjust client user */
	if (strcmp (rsComm->proxyUser.userName, rsComm->clientUser.userName) 
	  == 0) {
            authCheckOut->clientPrivLevel = authCheckOut->privLevel;
	} else {
	    zoneInfo_t *tmpZoneInfo;
	    status = getLocalZoneInfo (&tmpZoneInfo);
            if (status < 0) {
                free (authCheckOut);
                return status;
            }

	    if (strcmp (tmpZoneInfo->zoneName, rsComm->clientUser.rodsZone)
	      == 0) {
		/* client is from local zone */
        	if (authCheckOut->clientPrivLevel == REMOTE_PRIV_USER_AUTH) {
                    authCheckOut->clientPrivLevel = LOCAL_PRIV_USER_AUTH;
		} else if (authCheckOut->clientPrivLevel == REMOTE_USER_AUTH) {
                    authCheckOut->clientPrivLevel = LOCAL_USER_AUTH;
		}
	    } else {
		/* client is from remote zone */
                if (authCheckOut->clientPrivLevel == LOCAL_PRIV_USER_AUTH) {
                    authCheckOut->clientPrivLevel = REMOTE_USER_AUTH;
                } else if (authCheckOut->clientPrivLevel == LOCAL_USER_AUTH) {
                    authCheckOut->clientPrivLevel = REMOTE_USER_AUTH;
                }
	    }
	}
   } else if (strcmp (rsComm->proxyUser.userName, rsComm->clientUser.userName)
    == 0) {
        authCheckOut->clientPrivLevel = authCheckOut->privLevel;
   }

   status = chkProxyUserPriv (rsComm, authCheckOut->privLevel);

   if (status < 0) {
      free (authCheckOut);
      return status;
   } 

   rodsLog(LOG_NOTICE,
    "rsAuthResponse set proxy authFlag to %d, client authFlag to %d, user:%s proxy:%s client:%s",
          authCheckOut->privLevel,
          authCheckOut->clientPrivLevel,
          authCheckInp.username,
          rsComm->proxyUser.userName,
          rsComm->clientUser.userName);

   if (strcmp (rsComm->proxyUser.userName, rsComm->clientUser.userName) != 0) {
      rsComm->proxyUser.authInfo.authFlag = authCheckOut->privLevel;
      rsComm->clientUser.authInfo.authFlag = authCheckOut->clientPrivLevel;
   } else {	/* proxyUser and clientUser are the same */
      rsComm->proxyUser.authInfo.authFlag =
      rsComm->clientUser.authInfo.authFlag = authCheckOut->privLevel;
   } 

   /*** Added by RAJA Nov 16 2010 **/
   if (authCheckOut->serverResponse != NULL) free(authCheckOut->serverResponse);
   /*** Added by RAJA Nov 16 2010 **/
   free (authCheckOut);

   return (status);
} 
Example #2
0
    // =-=-=-=-=-=-=-
    // handle an agent-side auth request call
    irods::error osauth_auth_agent_response(
        irods::auth_plugin_context& _ctx,
        authResponseInp_t*           _resp ) {
        // =-=-=-=-=-=-=-
        // validate incoming parameters
        if ( !_ctx.valid().ok() ) {
            return ERROR(
                       SYS_INVALID_INPUT_PARAM,
                       "invalid plugin context" );
        }
        else if ( !_resp ) {
            return ERROR(
                       SYS_INVALID_INPUT_PARAM,
                       "null authResponseInp_t ptr" );
        }

        int status;
        char *bufp;
        authCheckInp_t authCheckInp;
        rodsServerHost_t *rodsServerHost;

        char digest[RESPONSE_LEN + 2];
        char md5Buf[CHALLENGE_LEN + MAX_PASSWORD_LEN + 2];
        char serverId[MAX_PASSWORD_LEN + 2];
        MD5_CTX context;

        bufp = _rsAuthRequestGetChallenge();

        // =-=-=-=-=-=-=-
        // need to do NoLogin because it could get into inf loop for cross
        // zone auth
        status = getAndConnRcatHostNoLogin(
                     _ctx.comm(),
                     MASTER_RCAT,
                     _ctx.comm()->proxyUser.rodsZone,
                     &rodsServerHost );
        if ( status < 0 ) {
            return ERROR(
                       status,
                       "getAndConnRcatHostNoLogin failed" );
        }

        memset( &authCheckInp, 0, sizeof( authCheckInp ) );
        authCheckInp.challenge = bufp;
        authCheckInp.username = _resp->username;

        std::string resp_str = irods::AUTH_SCHEME_KEY    +
                               irods::kvp_association()  +
                               irods::AUTH_OSAUTH_SCHEME +
                               irods::kvp_delimiter()    +
                               irods::AUTH_RESPONSE_KEY  +
                               irods::kvp_association()  +
                               _resp->response;
        authCheckInp.response = const_cast<char*>( resp_str.c_str() );

        authCheckOut_t *authCheckOut = NULL;
        if ( rodsServerHost->localFlag == LOCAL_HOST ) {
            status = rsAuthCheck( _ctx.comm(), &authCheckInp, &authCheckOut );
        }
        else {
            status = rcAuthCheck( rodsServerHost->conn, &authCheckInp, &authCheckOut );
            /* not likely we need this connection again */
            rcDisconnect( rodsServerHost->conn );
            rodsServerHost->conn = NULL;
        }
        if ( status < 0 || authCheckOut == NULL ) { // JMC cppcheck
            if ( authCheckOut != NULL ) {
                free( authCheckOut->serverResponse );
            }
            free( authCheckOut );
            return ERROR(
                       status,
                       "rxAuthCheck failed" );
        }

        if ( rodsServerHost->localFlag != LOCAL_HOST ) {
            if ( authCheckOut->serverResponse == NULL ) {
                rodsLog( LOG_NOTICE, "Warning, cannot authenticate remote server, no serverResponse field" );
                if ( requireServerAuth ) {
                    free( authCheckOut );
                    return ERROR(
                               REMOTE_SERVER_AUTH_NOT_PROVIDED,
                               "Authentication disallowed, no serverResponse field" );
                }
            }
            else {
                char *cp;
                int OK, len, i;
                if ( *authCheckOut->serverResponse == '\0' ) {
                    rodsLog( LOG_NOTICE, "Warning, cannot authenticate remote server, serverResponse field is empty" );
                    if ( requireServerAuth ) {
                        free( authCheckOut->serverResponse );
                        free( authCheckOut );
                        return ERROR(
                                   REMOTE_SERVER_AUTH_EMPTY,
                                   "Authentication disallowed, empty serverResponse" );
                    }
                }
                else {
                    char username2[NAME_LEN + 2];
                    char userZone[NAME_LEN + 2];
                    memset( md5Buf, 0, sizeof( md5Buf ) );
                    strncpy( md5Buf, authCheckInp.challenge, CHALLENGE_LEN );
                    parseUserName( _resp->username, username2, userZone );
                    getZoneServerId( userZone, serverId );
                    len = strlen( serverId );
                    if ( len <= 0 ) {
                        rodsLog( LOG_NOTICE, "rsAuthResponse: Warning, cannot authenticate the remote server, no RemoteZoneSID defined in server_config.json", status );
                        if ( requireServerAuth ) {
                            free( authCheckOut->serverResponse );
                            free( authCheckOut );
                            return ERROR(
                                       REMOTE_SERVER_SID_NOT_DEFINED,
                                       "Authentication disallowed, no RemoteZoneSID defined" );
                        }
                    }
                    else {
                        strncpy( md5Buf + CHALLENGE_LEN, serverId, len );
                        MD5_Init( &context );
                        MD5_Update( &context, ( unsigned char* )md5Buf,
                                   CHALLENGE_LEN + MAX_PASSWORD_LEN );
                        MD5_Final( ( unsigned char* )digest, &context );
                        for ( i = 0; i < RESPONSE_LEN; i++ ) {
                            if ( digest[i] == '\0' ) {
                                digest[i]++;
                            }  /* make sure 'string' doesn't
                                                                  end early*/
                        }
                        cp = authCheckOut->serverResponse;
                        OK = 1;
                        for ( i = 0; i < RESPONSE_LEN; i++ ) {
                            if ( *cp++ != digest[i] ) {
                                OK = 0;
                            }
                        }
                        rodsLog( LOG_DEBUG, "serverResponse is OK/Not: %d", OK );
                        if ( OK == 0 ) {
                            free( authCheckOut->serverResponse );
                            free( authCheckOut );
                            return ERROR(
                                       REMOTE_SERVER_AUTHENTICATION_FAILURE,
                                       "Server response incorrect, authentication disallowed" );
                        }
                    }
                }
            }
        }

        /* Set the clientUser zone if it is null. */
        if ( strlen( _ctx.comm()->clientUser.rodsZone ) == 0 ) {
            zoneInfo_t *tmpZoneInfo;
            status = getLocalZoneInfo( &tmpZoneInfo );
            if ( status < 0 ) {
                free( authCheckOut->serverResponse );
                free( authCheckOut );
                return ERROR(
                           status,
                           "getLocalZoneInfo failed" );
            }
            strncpy( _ctx.comm()->clientUser.rodsZone,
                     tmpZoneInfo->zoneName, NAME_LEN );
        }


        /* have to modify privLevel if the icat is a foreign icat because
         * a local user in a foreign zone is not a local user in this zone
         * and vice versa for a remote user
         */
        if ( rodsServerHost->rcatEnabled == REMOTE_ICAT ) {
            /* proxy is easy because rodsServerHost is based on proxy user */
            if ( authCheckOut->privLevel == LOCAL_PRIV_USER_AUTH ) {
                authCheckOut->privLevel = REMOTE_PRIV_USER_AUTH;
            }
            else if ( authCheckOut->privLevel == LOCAL_USER_AUTH ) {
                authCheckOut->privLevel = REMOTE_USER_AUTH;
            }

            /* adjust client user */
            if ( strcmp( _ctx.comm()->proxyUser.userName,  _ctx.comm()->clientUser.userName )
                    == 0 ) {
                authCheckOut->clientPrivLevel = authCheckOut->privLevel;
            }
            else {
                zoneInfo_t *tmpZoneInfo;
                status = getLocalZoneInfo( &tmpZoneInfo );
                if ( status < 0 ) {
                    free( authCheckOut->serverResponse );
                    free( authCheckOut );
                    return ERROR(
                               status,
                               "getLocalZoneInfo failed" );
                }

                if ( strcmp( tmpZoneInfo->zoneName,  _ctx.comm()->clientUser.rodsZone )
                        == 0 ) {
                    /* client is from local zone */
                    if ( authCheckOut->clientPrivLevel == REMOTE_PRIV_USER_AUTH ) {
                        authCheckOut->clientPrivLevel = LOCAL_PRIV_USER_AUTH;
                    }
                    else if ( authCheckOut->clientPrivLevel == REMOTE_USER_AUTH ) {
                        authCheckOut->clientPrivLevel = LOCAL_USER_AUTH;
                    }
                }
                else {
                    /* client is from remote zone */
                    if ( authCheckOut->clientPrivLevel == LOCAL_PRIV_USER_AUTH ) {
                        authCheckOut->clientPrivLevel = REMOTE_USER_AUTH;
                    }
                    else if ( authCheckOut->clientPrivLevel == LOCAL_USER_AUTH ) {
                        authCheckOut->clientPrivLevel = REMOTE_USER_AUTH;
                    }
                }
            }
        }
        else if ( strcmp( _ctx.comm()->proxyUser.userName,  _ctx.comm()->clientUser.userName )
                  == 0 ) {
            authCheckOut->clientPrivLevel = authCheckOut->privLevel;
        }

        status = check_proxy_user_privileges( _ctx.comm(), authCheckOut->privLevel );

        if ( status < 0 ) {
            free( authCheckOut->serverResponse );
            free( authCheckOut );
            return ERROR(
                       status,
                       "check_proxy_user_privileges failed" );
        }

        rodsLog( LOG_DEBUG,
                 "rsAuthResponse set proxy authFlag to %d, client authFlag to %d, user:%s proxy:%s client:%s",
                 authCheckOut->privLevel,
                 authCheckOut->clientPrivLevel,
                 authCheckInp.username,
                 _ctx.comm()->proxyUser.userName,
                 _ctx.comm()->clientUser.userName );

        if ( strcmp( _ctx.comm()->proxyUser.userName,  _ctx.comm()->clientUser.userName ) != 0 ) {
            _ctx.comm()->proxyUser.authInfo.authFlag = authCheckOut->privLevel;
            _ctx.comm()->clientUser.authInfo.authFlag = authCheckOut->clientPrivLevel;
        }
        else {	/* proxyUser and clientUser are the same */
            _ctx.comm()->proxyUser.authInfo.authFlag =
                _ctx.comm()->clientUser.authInfo.authFlag = authCheckOut->privLevel;
        }

        free( authCheckOut->serverResponse );
        free( authCheckOut );
        return SUCCESS();

    } // osauth_auth_agent_response