Beispiel #1
0
int
rsAuthCheck (rsComm_t *rsComm, authCheckInp_t *authCheckInp, 
		authCheckOut_t **authCheckOut)
{
#ifdef RODS_CAT
   int status;
   int privLevel;
   int clientPrivLevel;
   authCheckOut_t *result;
   unsigned char *digest;
   char md5Buf[CHALLENGE_LEN+MAX_PASSWORD_LEN+2];
   char ServerID[MAX_PASSWORD_LEN+2];

   *authCheckOut = (authCheckOut_t*)malloc(sizeof(authCheckOut_t));
   memset((char *)*authCheckOut, 0, sizeof(authCheckOut_t));

   rodsLog(LOG_NOTICE, "rsAuthCheck user %s", authCheckInp->username);
   status = chlCheckAuth(rsComm, authCheckInp->challenge, 
			 authCheckInp->response, 
			 authCheckInp->username,
			 &privLevel, &clientPrivLevel);
   if (status < 0) {
      rodsLog (LOG_NOTICE, 
	       "rsAuthCheck: chlCheckAuth status = %d", status);
   }

   if (status == 0) {
      int len, i;
      result = *authCheckOut;
      result->privLevel = privLevel;
      result->clientPrivLevel = clientPrivLevel;

      /* Add a hash to authenticate this server to the other server */
      memset(md5Buf, 0, sizeof(md5Buf));
      strncpy(md5Buf, authCheckInp->challenge, CHALLENGE_LEN);

      getZoneServerId("", ServerID); /* get our local zone SID */
      len = strlen(ServerID);
      digest = ( unsigned char* )malloc(RESPONSE_LEN+2);
      if (len <=0) {
	 rodsLog (LOG_DEBUG, 
	       "rsAuthCheck: Warning, cannot authenticate this server to remote server, no LocalZoneSID defined in server.config", status);
	 memset(digest, 0, RESPONSE_LEN);
      }
      else {
	 strncpy(md5Buf+CHALLENGE_LEN, ServerID, len);

	 obfMakeOneWayHash(
                           HASH_TYPE_DEFAULT, 
                           (unsigned char*)md5Buf, 
                           CHALLENGE_LEN+MAX_PASSWORD_LEN,
                           (unsigned char*)digest);

	 for (i=0;i<RESPONSE_LEN;i++) {
	    if (digest[i]=='\0') digest[i]++;  /* make sure 'string' doesn't
						  end early */
	 }
      }
      result->serverResponse = (char*)digest;
   }

   return (status);
#else
    /* this may be a gateway to the rcat host */
    rodsServerHost_t *rodsServerHost;
    int status;

   status = getAndConnRcatHostNoLogin (rsComm, MASTER_RCAT,
    rsComm->proxyUser.rodsZone, &rodsServerHost);

    if (status < 0) {
        rodsLog (LOG_NOTICE,
         "rsAuthCheck:getAndConnRcatHostNoLogin() failed. erro=%d", status);
        return (status);
    }

    if (rodsServerHost->localFlag == LOCAL_HOST) {
        return ( SYS_NO_ICAT_SERVER_ERR);
    } else {
        status = rcAuthCheck (rodsServerHost->conn, authCheckInp, authCheckOut);
    }
    return status;
#endif
} 
Beispiel #2
0
int
rsAuthCheck( rsComm_t *rsComm, authCheckInp_t *authCheckInp,
             authCheckOut_t **authCheckOut ) {
#ifdef RODS_CAT
    int status;
    int privLevel;
    int clientPrivLevel;
    authCheckOut_t *result;
    unsigned char *digest;
    char md5Buf[CHALLENGE_LEN + MAX_PASSWORD_LEN + 2];
    char ServerID[MAX_PASSWORD_LEN + 2];

    *authCheckOut = ( authCheckOut_t* )malloc( sizeof( authCheckOut_t ) );
    memset( ( char * )*authCheckOut, 0, sizeof( authCheckOut_t ) );

    // =-=-=-=-=-=-=-
    // the incoming response string might be a kvp string
    // holding the auth scheme as well as the response
    // try to parse it
    // NOTE :: incoming response string is longer than RESPONSE_LEN so we
    //         cannot directly assign it, it will need to be properly terminated
    //         and not contain any magic characters
    std::string scheme;
    std::string orig_resp = authCheckInp->response;
    std::string response  = authCheckInp->response;

    irods::kvp_map_t kvp;
    irods::error ret = irods::parse_kvp_string( orig_resp, kvp );
    if ( ret.ok() ) {
        if ( kvp.end() != kvp.find( irods::AUTH_SCHEME_KEY ) ) {
            scheme = kvp[ irods::AUTH_SCHEME_KEY ];

            // =-=-=-=-=-=-=-
            // subset the 'response' string from the incoming kvp set
            size_t response_key_pos = response.find( irods::AUTH_RESPONSE_KEY );
            if ( response_key_pos != std::string::npos ) {
                char *response_ptr = authCheckInp->response +
                                     ( response_key_pos +
                                       irods::AUTH_RESPONSE_KEY.length() +
                                       irods::KVP_DEF_ASSOCIATION.length() );
                response.assign( response_ptr, RESPONSE_LEN + 2 );
            }

        }
    }
    else {
        response.assign( authCheckInp->response, RESPONSE_LEN );

    }

    status = chlCheckAuth(
                 rsComm,
                 scheme.c_str(),
                 authCheckInp->challenge,
                 const_cast< char* >( response.c_str() ),
                 authCheckInp->username,
                 &privLevel,
                 &clientPrivLevel );
    if ( status < 0 ) {
        rodsLog( LOG_NOTICE,
                 "rsAuthCheck: chlCheckAuth status = %d", status );
    }

    if ( status == 0 ) {
        int len, i;
        result = *authCheckOut;
        result->privLevel = privLevel;
        result->clientPrivLevel = clientPrivLevel;

        /* Add a hash to authenticate this server to the other server */
        memset( md5Buf, 0, sizeof( md5Buf ) );
        strncpy( md5Buf, authCheckInp->challenge, CHALLENGE_LEN );

        getZoneServerId( "", ServerID ); /* get our local zone SID */
        len = strlen( ServerID );
        digest = ( unsigned char* )malloc( RESPONSE_LEN + 2 );
        if ( len <= 0 ) {
            rodsLog( LOG_DEBUG,
                     "rsAuthCheck: Warning, cannot authenticate this server to remote server, no LocalZoneSID defined in server_config.json", status );
            memset( digest, 0, RESPONSE_LEN );
        }
        else {
            strncpy( md5Buf + CHALLENGE_LEN, ServerID, len );

            obfMakeOneWayHash(
                HASH_TYPE_DEFAULT,
                ( unsigned char* )md5Buf,
                CHALLENGE_LEN + MAX_PASSWORD_LEN,
                ( unsigned char* )digest );

            for ( i = 0; i < RESPONSE_LEN; i++ ) {
                if ( digest[i] == '\0' ) {
                    digest[i]++;
                }  /* make sure 'string' doesn't
                                                      end early */
            }
        }
        result->serverResponse = ( char* )digest;
    }

    return status;
#else
    /* this may be a gateway to the rcat host */
    rodsServerHost_t *rodsServerHost;
    int status;

    status = getAndConnRcatHostNoLogin( rsComm, MASTER_RCAT,
                                        rsComm->proxyUser.rodsZone, &rodsServerHost );

    if ( status < 0 ) {
        rodsLog( LOG_NOTICE,
                 "rsAuthCheck:getAndConnRcatHostNoLogin() failed. erro=%d", status );
        return status;
    }

    if ( rodsServerHost->localFlag == LOCAL_HOST ) {
        return SYS_NO_ICAT_SERVER_ERR;
    }
    else {
        status = rcAuthCheck( rodsServerHost->conn, authCheckInp, authCheckOut );
    }
    return status;
#endif
}
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];

   bufp = _rsAuthRequestGetChallenge();

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

   status = getAndConnRcatHostNoLogin (rsComm, MASTER_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) {
      char username2[NAME_LEN+2];
      char userZone[NAME_LEN+2];
      int 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 (requireSIDs) {
	    rodsLog(LOG_NOTICE, "Authentication disallowed, no RemoteZoneSID defined");
	    return(REMOTE_SERVER_SID_NOT_DEFINED);  
	 }
      }
      else { 
	 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 {
	    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 {
	       int OK, i;
	       char *cp;
	       memset(md5Buf, 0, sizeof(md5Buf));
	       strncpy(md5Buf, authCheckInp.challenge, CHALLENGE_LEN);
	       strncpy(md5Buf+CHALLENGE_LEN, serverId, len);
	       obfMakeOneWayHash(
				 HASH_TYPE_DEFAULT,
				 (unsigned char*)md5Buf, 
				 CHALLENGE_LEN+MAX_PASSWORD_LEN,
				 (unsigned char*)digest);

	       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);
	       }
	    }
	 }
      }
   }

#ifdef STORAGE_ADMIN_ROLE
   /* if the user is a storage admin, this will be indicated with
      a bit in authCheckOut->privLevel. If it's set, set the userType
      in rsComm->proxyUser to 'storageadmin' and clear the bit so
      it doesn't affect subsequent checks */
   if (authCheckOut->privLevel & STORAGE_ADMIN_USER) {
     strncpy(rsComm->proxyUser.userType, STORAGE_ADMIN_USER_TYPE, NAME_LEN);
     authCheckOut->privLevel &= ~STORAGE_ADMIN_USER;
   }
#endif

   /* 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_USER_AUTH)
            authCheckOut->privLevel = REMOTE_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);
}