Ejemplo n.º 1
0
int
Condor_Auth_Passwd::authenticate(const char * /* remoteHost */, 
								 CondorError* /* errstack */ )
{
    int client_status = AUTH_PW_A_OK;
    int server_status = AUTH_PW_A_OK;
	int ret_value = -1;
    
    struct msg_t_buf t_client;
    struct msg_t_buf t_server;

		// In order to create the shared keys used by the client and
		// the server in this protocol, we take a single shared secret
		// and hmac it twice with two different keys.  The original
		// password buffer and the two generated keys are stored in
		// the sk_buf structure.
    struct sk_buf sk;

	int tmp_rv;

		// Initialize these structures (with NULLs)
    init_t_buf(&t_client);
    init_t_buf(&t_server);
    init_sk(&sk);
	dprintf(D_SECURITY, "PW.\n");

	if ( mySock_->isClient() ) {
			// ** client side authentication **
        
			// Get my name, password and setup the shared keys based
			// on this data.  The server will do the same when it
			// learns my name.
		dprintf(D_SECURITY, "PW: getting name.\n");
        t_client.a = fetchLogin();

			// We complete the entire protocol even if there's an
			// error, but there's no point trying to actually do any
			// work.  This is protocol step (a).
		dprintf(D_SECURITY, "PW: Generating ra.\n");
	        
        if(client_status == AUTH_PW_A_OK) {
			t_client.ra = Condor_Crypt_Base::randomKey(AUTH_PW_KEY_LEN);
			if(!t_client.ra) {
				dprintf(D_SECURITY, "Malloc error in random key?\n");
				client_status = AUTH_PW_ERROR;
			}
        }
        
			// This differs from the protocol description in the book
			// only that the client also sends its name "A".  The
			// protocol doesn't mention how the peers know who they're
			// talking to.  This is also protocol step (a).
		dprintf(D_SECURITY, "PW: Client sending.\n");
        client_status = client_send_one(client_status, &t_client);

		if(client_status == AUTH_PW_ABORT) {
			goto client_abort;
		}
			// This is protocol step (b).
		dprintf(D_SECURITY, "PW: Client receiving.\n");
        server_status = client_receive(&client_status, &t_server);
		if(client_status == AUTH_PW_ABORT) {
			goto client_abort;
		}

			// Now that we've received the server's name, we can go
			// ahead and setup the keys.
		if(client_status == AUTH_PW_A_OK && server_status == AUTH_PW_A_OK) {
			sk.shared_key = fetchPassword(t_client.a, t_server.b);
			dprintf(D_SECURITY, "PW: Client setting keys.\n");
			if(!setup_shared_keys(&sk)) {
				client_status = AUTH_PW_ERROR;
			}
		}

			// This is protocol step (c).
		if(client_status == AUTH_PW_A_OK
		   && server_status == AUTH_PW_A_OK) {
			dprintf(D_SECURITY, "PW: Client checking T.\n");
			client_status = client_check_t_validity(&t_client, &t_server, &sk);
		}

			// Are we copying the data into the t_client struct?
			// This is protocol step (d).  Server does (e).
		dprintf(D_SECURITY, "PW: CLient sending two.\n");
        client_status = client_send_two(client_status, &t_client, &sk);
		if(client_status == AUTH_PW_ABORT) {
			goto client_abort;
		}

	client_abort:
			// This is protocol step (f).
		if(client_status == AUTH_PW_A_OK
		   && server_status == AUTH_PW_A_OK
		   && set_session_key(&t_client, &sk)) {
			dprintf(D_SECURITY, "PW: CLient set session key.\n");
			ret_value = 1;
		} else {
			ret_value = 0;
		}
	}
	else {
			// ** server side authentication **
		
			// First we get the client's name and ra, protocol step
			// (a).
		dprintf(D_SECURITY, "PW: Server receiving 1.\n");
		client_status = server_receive_one(&server_status, &t_client);
		if(client_status == AUTH_PW_ABORT || server_status == AUTH_PW_ABORT) {
			goto server_abort;
		}

			// Then we do the key setup, and generate the random string.
		if(client_status == AUTH_PW_A_OK && server_status == AUTH_PW_A_OK) {
			t_server.b = fetchLogin();
			dprintf(D_SECURITY, "PW: Server fetching password.\n");
			sk.shared_key = fetchPassword(t_client.a, t_server.b);
			if(!setup_shared_keys(&sk)) {
				server_status = AUTH_PW_ERROR;
			} else {
				dprintf(D_SECURITY, "PW: Server generating rb.\n");
		//server_status = server_gen_rand_rb(&t_server);
	            t_server.rb = Condor_Crypt_Base::randomKey(AUTH_PW_KEY_LEN);
				if(t_client.a) {
					t_server.a = strdup(t_client.a);
				} else {
					t_server.a = NULL;
				}
				t_server.ra = (unsigned char *)malloc(AUTH_PW_KEY_LEN);
				if(!t_server.ra || !t_server.rb) {
					dprintf(D_SECURITY, "Malloc error 1.\n"); 
					server_status = AUTH_PW_ERROR;
				} else {
					memcpy(t_server.ra, t_client.ra, AUTH_PW_KEY_LEN);
				}
			}
		}

			// Protocol message (2), step (b).
		dprintf(D_SECURITY, "PW: Server sending.\n");
		tmp_rv = server_send(server_status, &t_server, &sk);
		if(server_status == AUTH_PW_A_OK) {
			server_status = tmp_rv;
		}
		if(server_status == AUTH_PW_ABORT) {
			goto server_abort;
		}

			// Protocol step (d)
		dprintf(D_SECURITY, "PW: Server receiving 2.\n");
		if(t_server.a) {
			t_client.a = strdup(t_server.a);
		} else { 
			t_client.a = NULL;
		}
        if(server_status == AUTH_PW_A_OK) {
			t_client.rb = (unsigned char *)malloc(AUTH_PW_KEY_LEN);
			if(!t_client.rb) {
				dprintf(D_SECURITY, "Malloc_error.\n");
				server_status = AUTH_PW_ERROR;
			} else {
				memcpy(t_client.rb, t_server.rb, AUTH_PW_KEY_LEN);
			}
		} else {
			t_client.rb = NULL;
		}
		client_status = server_receive_two(&server_status, &t_client);

		if(server_status == AUTH_PW_A_OK
		   && client_status == AUTH_PW_A_OK) {
				// Protocol step (e)
			dprintf(D_SECURITY, "PW: Server checking hk.\n");
			server_status = server_check_hk_validity(&t_client, 
													 &t_server, &sk);
		}
		
	server_abort:
				// protocol step (f)
		if(client_status == AUTH_PW_A_OK
		   && server_status == AUTH_PW_A_OK
		   && set_session_key(&t_server, &sk)) {
			dprintf(D_SECURITY, "PW: Server set session key.\n");
			ret_value = 1;
		} else {
			ret_value = 0;
		}
		
	}

		//ret_value is 1 for success, 0 for failure.
	if ( ret_value == 1 ) {
			// if all is good, set the remote user and domain names
		char *login, *domain;
		if ( mySock_->isClient() ) {
			login = t_server.b;	// server is remote to client
		} else {
			login = t_client.a; // client is remote to server
		}
		ASSERT(login);
		domain = strchr(login,'@');
		if (domain) {
			*domain='\0';
			domain++;
		}

		setRemoteUser(login);
		setRemoteDomain(domain);
	}

	destroy_t_buf(&t_client);
	destroy_t_buf(&t_server);
	destroy_sk(&sk);

		//return 1 for success, 0 for failure. Server should send
		//sucess/failure back to client so client can know what to
		//return.
	return ret_value;
}
Ejemplo n.º 2
0
int main(int argc, char **argv)
{
  int status;
  char ip_addr[INET_ADDRSTRLEN];
  char *service;
  int server_sock = -1;
  int exit_flag = 0;
  int ftp_sock = 9999;

  fd_set temp;

  /*Init. Logger*/
#ifndef MY_PC
  cse4589_init_log(argv[2]);
#endif

  int sock;
  if(argc<3)
  {
    printf("No args\n");
    return 1;
  }
  if(!validate_port(argv[2]))
    return 0;

  FD_ZERO(&wait_fd);
  FD_ZERO(&temp);
  FD_SET(0, &wait_fd);
  tv.tv_sec = 15;
  tv.tv_usec = 0;

  if(!strcmp(argv[1], "s"))
  {
    is_server = true;
  }
  else if(strcmp(argv[1], "c"))
  {
    printf("Usage ./sock [s/c]\n");
    return 0;
  }
  set_listening_port(argv[2]);
  server_sock = server_start(argv[2]);
  if(server_sock <=0)return 0;
  sock = server_sock;
  add_fd(sock);

  int i =2;
  while(!exit_flag)
  {
    temp = wait_fd;
    int ret = select(active_sockets, &temp, NULL, NULL, NULL);
    if(ret)
    {
      if(FD_ISSET(STDIN, &temp))
      {
        exit_flag = parse_shell();
      }
      else if(FD_ISSET(server_sock, &temp))
      {
        // server socket is active, check for new connections
        if(is_server)
        {
          int new_socket = server_accept(server_sock);
          add_fd(new_socket);
        }
        else
        {
          int new_socket = server_accept(server_sock);
          //add ftp socket
          add_fd(new_socket);
          ftp_sock = new_socket;
        }
      }
      else if(FD_ISSET(ftp_sock, &temp))
      {
        client_receive_file(&ftp_sock);
      }
      else
      {
        for(int fd = 3; fd<=active_sockets; fd++)
        {
          if(FD_ISSET(fd, &temp))
          {
            if(is_server)
              server_receive(fd);
            else
              client_receive(fd);
          }
        }
      } //End of else
    } //end of select handling
  } //end loop
  clear_fd(sock);
  close(sock);
#ifndef MY_PC
  fclose(fopen(LOGFILE, "w"));
#endif
  return 0;
}