示例#1
0
int vrpn_File_Connection::reset()
{
    // make it as if we never saw any messages from our previous activity
    d_endpoints[0]->drop_connection();

    // If we are accumulating, reset us back to the beginning of the memory
    // buffer chain. Otherwise, go back to the beginning of the file and
    // then read the magic cookie and then the first entry again.
    if (d_accumulate) {
      d_currentLogEntry = d_startEntry;
    } else {
      rewind(d_file);
      read_cookie();
      read_entry();
      d_startEntry = d_currentLogEntry = d_logHead;
    }
    d_time = d_startEntry->data.msg_time;
    // reset for mainloop()
    d_last_time.tv_usec = d_last_time.tv_sec = 0;
    d_filetime_accum.reset_at_time( d_last_time );
    
    // This is useful to play the initial system messages
    // (the sender/type ones) automatically.  These might not be
    // time synched so if we don't play them automatically they
    // can mess up playback if their timestamps are later then
    // the first user message.
    if (vrpn_FILE_CONNECTIONS_SHOULD_SKIP_TO_USER_MESSAGES) {
        play_to_user_message();
    }

    return 0;
}
示例#2
0
    int
f_logout( SNET *sn, int ac, char *av[], SNET *pushersn )
{
    struct cinfo	ci;
    char		path[ MAXPATHLEN ];

    /* LOGOUT login_cookie ip */

    if ( al->al_key != CGI ) {
	syslog( LOG_ERR, "f_logout: %s not allowed", al->al_hostname );
	snet_writef( sn, "%d LOGOUT: %s not allowed to logout.\r\n",
		410, al->al_hostname );
	return( 1 );
    }

    if ( ac != 3 ) {
	syslog( LOG_ERR, "f_logout: %s wrong number of args", al->al_hostname );
	snet_writef( sn, "%d LOGOUT: Wrong number of args.\r\n", 510 );
	return( 1 );
    }

    if ( mkcookiepath( NULL, hashlen, av[ 1 ], path, sizeof( path )) < 0 ) {
	syslog( LOG_ERR, "f_login: mkcookiepath error" );
	snet_writef( sn, "%d LOGIN: Invalid cookie path.\r\n", 511 );
	return( 1 );
    }

    if ( read_cookie( path, &ci ) != 0 ) {
	snet_writef( sn, "%d LOGOUT error: Sorry\r\n", 513 );
	return( 1 );
    }

    /* double action policy?? */
    if ( ci.ci_state == 0 ) {
	syslog( LOG_ERR, "f_logout: %s already logged out", av[ 1 ] );
	snet_writef( sn, "%d LOGOUT: Already logged out\r\n", 411 );
	return( 1 );
    }

    if ( do_logout( path ) < 0 ) {
	syslog( LOG_ERR, "f_logout: %s: %m", path );
	return( -1 );
    }

    snet_writef( sn, "%d LOGOUT successful: cookie no longer valid\r\n", 210 );
    if (( pushersn != NULL ) && ( !replicated )) {
	snet_writef( pushersn, "LOGOUT %s %s\r\n", av[ 1 ], av [ 2 ] );
    }
    if ( !replicated ) {
	syslog( LOG_INFO, "LOGOUT %s %s %s", ci.ci_user, ci.ci_realm, av[ 2 ] );
    }
    return( 0 );

}
示例#3
0
文件: cnode.c 项目: ShoreTel-Inc/erld
int start_cnode(const char *cookie_file, ei_cnode *ec, int *epmd_sock, int *listen_sock, const char *reg_name, const char *host_name) {
	char *cookie = 0, *default_node_name = 0, *node_name;
	short creation = 0;
	int s, port, pub, tries;
	socklen_t addr_len;
	struct sockaddr_in addr;

	cookie = read_cookie(cookie_file);
	node_name = (char *)malloc(strlen(reg_name) + strlen(host_name) + 2);
	strcpy(node_name, reg_name);
	strcat(node_name, "@");
	strcat(node_name, host_name);
	/* The thisipaddr parameter is unused at the moment (R13B01). */
	ei_connect_xinit(ec, host_name, reg_name, node_name, 0, cookie, creation);

	if (cookie)
		free(cookie);
	if (default_node_name)
		free(default_node_name);
	free(node_name);

	s = open_port();
	addr_len = sizeof addr;
	getsockname(s, (struct sockaddr *)&addr, &addr_len);
	port = ntohs(addr.sin_port);
	DEBUG_V("bound port %d", port);

	/* It's possible that epmd has been started, but hasn't yet finished starting
	 * up, so we have a few goes at connecting. Like erl, epmd goes directly into
	 * the background when started, not indicating when it's ready. */
	DEBUG("connecting to epmd");
	tries = 0;
	while (1) {
		pub = ei_publish(ec, port);
		if (pub != -1)
			break;
		if (!tries)
			fprintf(stderr, "Waiting for connection to epmd.\n");
		if (tries++ < ERLD_MAX_TRIES) {
			if (debug_flag)
				erl_err_ret("epmd connection failed, polling (attempt %d/%d)", tries, ERLD_MAX_TRIES);
			usleep(ERLD_POLL_TIME * 1000);
		}
		else {
			erl_err_ret("Unable to connect to epmd");
			return -1;
		}
	}
	*epmd_sock = pub;
	*listen_sock = s;
	return 0;
}
示例#4
0
vrpn_File_Connection::vrpn_File_Connection (const char * station_name,
                         const char * local_in_logfile_name,
                         const char * local_out_logfile_name) :
    vrpn_Connection (local_in_logfile_name, local_out_logfile_name, NULL, NULL),
    d_controllerId (register_sender("vrpn File Controller")),
    d_set_replay_rate_type(register_message_type("vrpn_File set_replay_rate")),
    d_reset_type (register_message_type("vrpn_File reset")),
    d_play_to_time_type (register_message_type("vrpn_File play_to_time")),
    d_fileName (NULL),
    d_file (NULL),
    d_logHead (NULL),
    d_logTail (NULL),
    d_currentLogEntry (NULL),
    d_preload(vrpn_FILE_CONNECTIONS_SHOULD_PRELOAD),
    d_accumulate(vrpn_FILE_CONNECTIONS_SHOULD_ACCUMULATE)
{
    // Because we are a file connection, our status should be CONNECTED
    // Later set this to BROKEN if there is a problem opening/reading the file.
    if (d_endpoints[0] == NULL) {
      fprintf(stderr,"vrpn_File_Connection::vrpn_File_Connection(): NULL zeroeth endpoint\n");
    } else {
      connectionStatus = CONNECTED;
      d_endpoints[0]->status = CONNECTED;
    }

    // If we are preloading, then we must accumulate messages.
    if (d_preload) {
      d_accumulate = true;
    }

    // These are handlers for messages that may be sent from a
    // vrpn_File_Controller object that may attach itself to us.
    register_handler(d_set_replay_rate_type, handle_set_replay_rate,
                     this, d_controllerId);
    register_handler(d_reset_type, handle_reset, this, d_controllerId);
    register_handler(d_play_to_time_type, handle_play_to_time,
                     this, d_controllerId);

    // necessary to initialize properly in mainloop()
    d_last_time.tv_usec = d_last_time.tv_sec = 0;
    
    d_fileName = vrpn_copy_file_name(station_name);
    if (!d_fileName) {
        fprintf(stderr, "vrpn_File_Connection:  Out of memory!\n");
        connectionStatus = BROKEN;
        return;
    }

    d_file = fopen(d_fileName, "rb");
    if (!d_file) {
        fprintf(stderr, "vrpn_File_Connection:  "
                "Could not open file \"%s\".\n", d_fileName);
        connectionStatus = BROKEN;
        return;
    }

    // Read the cookie from the file.  It will print an error message if it
    // can't read it, so we just pass the broken status on up the chain.
    if (read_cookie() < 0) {
	connectionStatus = BROKEN;
	return;
    }

    // If we are supposed to preload the entire file into memory buffers,
    // then keep reading until we get to the end.  Otherwise, just read the
    // first message to get things going.
    if (d_preload) {
      while (!read_entry()) { }
    } else {
      read_entry();
    }

    // Initialize the "current message" pointer to the first log-file
    // entry that was read, and set the start time for the file and
    // the current time to the one in this message.
    if (d_logHead) {
      d_currentLogEntry = d_logHead;
      d_startEntry = d_logHead;
      d_start_time = d_startEntry->data.msg_time;  
      d_time = d_start_time;
      d_earliest_user_time.tv_sec = d_earliest_user_time.tv_usec = 0;
      d_earliest_user_time_valid = false;
      d_highest_user_time.tv_sec = d_highest_user_time.tv_usec = 0;
      d_highest_user_time_valid = false;
    } else {
      fprintf(stderr, "vrpn_File_Connection: Can't read first message\n");
      connectionStatus = BROKEN;
      return;
    }

    // This is useful to play the initial system messages
    // (the sender/type ones) automatically.  These might not be
    // time synched so if we don't play them automatically they
    // can mess up playback if their timestamps are later then
    // the first user message.
    if (vrpn_FILE_CONNECTIONS_SHOULD_SKIP_TO_USER_MESSAGES) {
	play_to_user_message();
	if (d_currentLogEntry) {
	    d_start_time = d_currentLogEntry->data.msg_time;
	    d_time = d_start_time;
	}
    }

    // Add this to the list of known connections.
    vrpn_ConnectionManager::instance().addConnection(this, station_name);
}
示例#5
0
    int
f_check( SNET *sn, int ac, char *av[], SNET *pushersn )
{
    struct cinfo 	ci;
    struct timeval	tv;
    char		login[ MAXCOOKIELEN ], path[ MAXPATHLEN ];
    char		rekeybuf[ 128 ], rcookie[ 256 ], scpath[ MAXPATHLEN ];
    char		*p;
    int			status;
    double		rate;

    /*
     * C: CHECK servicecookie
     * S: 231 ip principal realm
     */

    /*
     * C: CHECK logincookie
     * S: 232 ip principal realm
     */

    /*
     * C: REKEY servicecookie
     * S: 233 ip principal realm rekeyed-cookie
     */

    if (( al->al_key != CGI ) && ( al->al_key != SERVICE )) {
	syslog( LOG_ERR, "f_check: %s not allowed", al->al_hostname );
	snet_writef( sn, "%d %s: %s not allowed to check.\r\n",
		430, av[ 0 ], al->al_hostname );
	return( 1 );
    }

    if ( ac < 2 || ac > 3 ) {
	syslog( LOG_ERR, "f_check: %s: wrong number of args. "
		"Expected 2 or 3, got %d", al->al_hostname, ac );
	snet_writef( sn, "%d %s: Wrong number of args.\r\n", 530, av[ 0 ] );
	return( 1 );
    }

    if ( mkcookiepath( NULL, hashlen, av[ 1 ], path, sizeof( path )) < 0 ) {
	syslog( LOG_ERR, "f_check: mkcookiepath error" );
	snet_writef( sn, "%d %s: Invalid cookie name.\r\n", 531, av[ 0 ] );
	return( 1 );
    }

    if ( strncmp( av[ 1 ], "cosign-", 7 ) == 0 ) {
	if ( strict_checks && service_valid( av[ 1 ] ) == NULL ) {
	    snet_writef( sn, "%d %s: Invalid cookie\r\n", 534, av[ 0 ] );
	    return( 1 );
	}

	status = 231;
	if ( service_to_login( path, login ) != 0 ) {
	    if (( rate = rate_tick( &checkunknown )) != 0.0 ) {
		syslog( LOG_NOTICE, "STATS CHECK %s: UNKNOWN %.5f / sec",
			inet_ntoa( cosign_sin.sin_addr), rate );
	    }
	    snet_writef( sn, "%d %s: cookie not in db!\r\n", 533, av[ 0 ] );
	    return( 1 );
	}
	if ( COSIGN_PROTO_SUPPORTS_REKEY( protocol )) {
	    if ( strcasecmp( av[ 0 ], "REKEY" ) == 0 ) {

		/* save service cookie path for rekeying below. */
		if ( strlen( path ) >= sizeof( scpath )) {
		    syslog( LOG_ERR, "f_check: %s exceeds bounds.", path );
		    snet_writef( sn, "%d %s: Invalid cookie name.\r\n",
				 531, av[ 0 ]);
		    return( 1 );
		}
		strcpy( scpath, path );

		status = 233;
	    }
	}

	if ( mkcookiepath( NULL, hashlen, login, path, sizeof( path )) < 0 ) {
	    syslog( LOG_ERR, "f_check: mkcookiepath error.." );
	    snet_writef( sn, "%d %s: Invalid cookie name.\r\n", 532, av[ 0 ] );
	    return( 1 );
	}
    } else if ( strncmp( av[ 1 ], "cosign=", 7 ) == 0 ) {
	status = 232;
    } else {
	syslog( LOG_ERR, "f_check: unknown cookie prefix." );
	snet_writef( sn, "%d %s: unknown cookie prefix!\r\n", 432, av[ 0 ] );
	return( 1 );
    }

    if ( read_cookie( path, &ci ) != 0 ) {
	if (( rate = rate_tick( &checkunknown )) != 0.0 ) {
	    syslog( LOG_NOTICE, "STATS CHECK %s: UNKNOWN %.5f / sec",
		    inet_ntoa( cosign_sin.sin_addr), rate);
	}
	snet_writef( sn, "%d %s: Who me? Dunno.\r\n", 534, av[ 0 ] );
	return( 1 );
    }

    if ( ci.ci_state == 0 ) {
	if (( rate = rate_tick( &checkfail )) != 0.0 ) {
	    syslog( LOG_NOTICE, "STATS CHECK %s: FAIL %.5f / sec",
		    inet_ntoa( cosign_sin.sin_addr), rate);
	}
	snet_writef( sn, "%d %s: Already logged out\r\n", 430, av[ 0 ] );
	return( 1 );
    }

    /* check for idle timeout, and if so, log'em out */
    if ( gettimeofday( &tv, NULL ) != 0 ){
	syslog( LOG_ERR, "f_check: gettimeofday: %m" );
	return( -1 );
    }

    if ( tv.tv_sec - ci.ci_itime >= idle_out_time ) {
	if ( tv.tv_sec - ci.ci_itime < ( idle_out_time + grey_time )) {
	    if (( rate = rate_tick( &checkunknown )) != 0.0 ) {
		syslog( LOG_NOTICE, "STATS CHECK %s: UNKNOWN %.5f / sec",
			inet_ntoa( cosign_sin.sin_addr ), rate );
	    }
	    syslog( LOG_NOTICE, "f_check: idle grey window" );
	    snet_writef( sn, "%d %s: Idle Grey Window\r\n", 531, av[ 0 ] );
	    return( 1 );
	}
	if (( rate = rate_tick( &checkfail )) != 0.0 ) {
	    syslog( LOG_NOTICE, "STATS CHECK %s: FAIL %.5f / sec",
		    inet_ntoa( cosign_sin.sin_addr), rate);
	}
	snet_writef( sn, "%d %s: Idle logged out\r\n", 431, av[ 0 ] );
	if ( do_logout( path ) < 0 ) {
	    syslog( LOG_ERR, "f_check: %s: %m", login );
	    return( -1 );
	}
	return( 1 );
    }

    /* prevent idle out if we are actually using it */
    utime( path, NULL );

    if (( rate = rate_tick( &checkpass )) != 0.0 ) {
	syslog( LOG_NOTICE, "STATS CHECK %s: PASS %.5f / sec",
		inet_ntoa( cosign_sin.sin_addr), rate);
    }

    if ( status == 233 ) {
	/* rekey service cookie. */

	if ( mkcookie( sizeof( rekeybuf ), rekeybuf ) != 0 ) {
	    syslog( LOG_ERR, "f_check: rekey: mkcookie failed" );
	    snet_writef( sn, "%d %s: rekey failed.\r\n", 536, av[ 0 ] );
	    return( 1 );
	}
	if (( p = strchr( av[ 1 ], '=' )) == NULL ) {
	    syslog( LOG_ERR, "f_check: rekey: bad service name \"%s\".", av[1]);
	    snet_writef( sn, "%d %s rekey failed.\r\n", 536, av[ 0 ] );
	    return( 1 );
	}
	*p = '\0';
	if ( snprintf( rcookie, sizeof( rcookie ), "%s=%s", av[ 1 ], rekeybuf )
		>= sizeof( rcookie )) {
	    syslog( LOG_ERR, "f_check: rekey: new cookie too long." );
	    snet_writef( sn, "%d %s rekey failed.\r\n", 536, av[ 0 ] );
	    return( 1 );
	}
	*p = '=';
	if ( mkcookiepath( NULL, hashlen, rcookie, path, sizeof( path )) < 0 ) {
	    syslog( LOG_ERR, "f_check: rekey: mkcookiepath error." );
	    snet_writef( sn, "%d %s: rekey failed.\r\n", 536, av[ 0 ] );
	    return( 1 );
	}
	if ( rename( scpath, path ) != 0 ) {
	    syslog( LOG_ERR, "f_check: rekey: rename %s to %s failed: %s.",
			scpath, path, strerror( errno ));
	    snet_writef( sn, "%d %s: rekey failed.\r\n", 536, av[ 0 ] );
	    return( 1 );
	}
    }

    if ( COSIGN_PROTO_SUPPORTS_FACTORS( protocol )) {
	snet_writef( sn, "%d %s %s %s %s\r\n",
		status, ci.ci_ipaddr_cur, ci.ci_user, ci.ci_realm,
		( status == 233 ? rcookie : "" ));
    } else {
	/* if there is more than one realm, we just give the first */
	if (( p = strtok( ci.ci_realm, " " )) != NULL ) {
	    snet_writef( sn, "%d %s %s %s\r\n",
		    status, ci.ci_ipaddr, ci.ci_user, p );
	} else {
	    snet_writef( sn, "%d %s %s %s\r\n",
		    status, ci.ci_ipaddr, ci.ci_user, ci.ci_realm );
	}

    }
    return( 0 );
}
示例#6
0
    int
f_register( SNET *sn, int ac, char *av[], SNET *pushersn )
{
    struct cinfo	ci;
    struct timeval	tv;
    int			rc;
    char		lpath[ MAXPATHLEN ], spath[ MAXPATHLEN ];

    /* REGISTER login_cookie ip service_cookie */

    if ( al->al_key != CGI ) {
	syslog( LOG_ERR, "f_register: %s not allowed", al->al_hostname );
	snet_writef( sn, "%d REGISTER: %s not allowed to register.\r\n",
		420, al->al_hostname );
	return( 1 );
    }

    if ( ac != 4 ) {
	syslog( LOG_ERR, "f_register: %s wrong number of args.",
		al->al_hostname );
	snet_writef( sn, "%d REGISTER: Wrong number of args.\r\n", 520 );
	return( 1 );
    }

    if ( mkcookiepath( NULL, hashlen, av[ 1 ], lpath, sizeof( lpath )) < 0 ) {
	syslog( LOG_ERR, "f_register: mkcookiepath login cookie error" );
	snet_writef( sn, "%d REGISTER: Invalid cookie path.\r\n", 521 );
	return( 1 );
    }

    if ( mkcookiepath( NULL, hashlen, av[ 3 ], spath, sizeof( spath )) < 0 ) {
	syslog( LOG_ERR, "f_register: mkcookiepath service cookie error" );
	snet_writef( sn, "%d REGISTER: Invalid cookie path.\r\n", 522 );
	return( 1 );
    }

    if ( read_cookie( lpath, &ci ) != 0 ) {
	snet_writef( sn, "%d REGISTER error: Sorry\r\n", 523 );
	return( 1 );
    }

    if ( ci.ci_state == 0 ) {
	syslog( LOG_ERR,
		"f_register: %s logged out, can't register", ci.ci_user );
	snet_writef( sn, "%d REGISTER: Already logged out\r\n", 421 );
	return( 1 );
    }

    /* check for idle timeout, and if so, log'em out */
    if ( gettimeofday( &tv, NULL ) != 0 ){
	syslog( LOG_ERR, "f_register: gettimeofday: %m" );
	return( -1 );
    }

    if ( tv.tv_sec - ci.ci_itime >= idle_out_time ) {
	if ( tv.tv_sec - ci.ci_itime < ( idle_out_time + grey_time )) {
	    syslog( LOG_NOTICE, "f_register: idle grey window" );
	    snet_writef( sn, "%d REGISTER: Idle Grey Window\r\n", 521 );
	    return( 1 );
	}
	snet_writef( sn, "%d REGISTER: Idle logged out\r\n", 422 );
	if ( do_logout( lpath ) < 0 ) {
	    syslog( LOG_ERR, "f_register: %s: %m", lpath );
	    return( -1 );
	}
	return( 1 );
    }

    if (( rc = do_register( av[ 1 ], lpath, spath )) < 0 ) {
	return( -1 );
    }

    /* double action policy?? */
    if ( rc > 0 ) {
	snet_writef( sn,
		"%d REGISTER error: Cookie already exists\r\n", 226 );
	return( rc );
    }

    snet_writef( sn, "%d REGISTER successful: Cookie Stored.\r\n", 220 );
    if (( pushersn != NULL ) && ( !replicated )) {
	snet_writef( pushersn, "REGISTER %s %s %s\r\n",
		av[ 1 ], av[ 2 ], av [ 3 ] );
    }
    if ( !replicated ) {
	/* just log service name, no need for full cookie */
	(void)strtok( av[ 3 ], "=" );
	syslog( LOG_INFO, "REGISTER %s %s %s %s", 
		ci.ci_user, ci.ci_realm, ci.ci_ipaddr, av[ 3 ] );
    }
    return( 0 );
}
示例#7
0
    int
f_login( SNET *sn, int ac, char *av[], SNET *pushersn )
{
    FILE		*tmpfile;
    ACAV		*facav;
    char		tmppath[ MAXCOOKIELEN ], path[ MAXPATHLEN ];
    char		tmpkrb[ 16 ], krbpath [ MAXPATHLEN ];
    char                *sizebuf, *line;
    char                buf[ 8192 ];
    char		**fv;
    int			fd, i, j, fc, already_krb = 0;
    int			krb = 0, err = 1, addinfo = 0, newinfo = 0;
    struct timeval	tv;
    struct cinfo	ci;
    unsigned int        len, rc;
    extern int		errno;

    /*
     * C: LOGIN login_cookie ip principal factor [factor2]
     * S: 200 LOGIN successful: Cookie Stored.
     */

    /*
     * C: LOGIN login_cookie ip principal factor "kerberos"
     * S: 300 LOGIN: Send length then file.
     * C: [length]
     * C: [data]
     * C: .
     */

    if ( al->al_key != CGI ) {
	syslog( LOG_ERR, "%s not allowed to login", al->al_hostname );
	snet_writef( sn, "%d LOGIN: %s not allowed to login.\r\n",
		400, al->al_hostname );
	return( 1 );
    }

    if ( ac < 5 ) {
	syslog( LOG_ERR, "f_login: got %d args, need at least 5", ac );
	snet_writef( sn, "%d LOGIN: Wrong number of args.\r\n", 500 );
	return( 1 );
    }

    if ( ac >= 6 ) {
	if ( strcmp( av[ ac - 1 ], "kerberos" ) == 0 ) {
	    krb = 1;
	    ac--;
	    if ( mkcookie( sizeof( tmpkrb ), tmpkrb ) != 0 ) {
		syslog( LOG_ERR, "f_login: mkcookie error." );
		return( -1 );
	    }
	    if ( snprintf( krbpath, sizeof( krbpath ), "%s/%s",
		    cosign_tickets, tmpkrb ) >= sizeof( krbpath )) {
		syslog( LOG_ERR, "f_login: krbpath too long." );
		return( -1 );
	    }
	}
    }

    if ( mkcookiepath( NULL, hashlen, av[ 1 ], path, sizeof( path )) < 0 ) {
	syslog( LOG_ERR, "f_login: mkcookiepath error" );
	snet_writef( sn, "%d LOGIN: Invalid cookie path.\r\n", 501 );
	return( 1 );
    }

    if ( read_cookie( path, &ci ) == 0 ) {
	addinfo = 1;
	if ( ci.ci_state == 0 ) {
	    syslog( LOG_ERR,
		    "f_login: %s already logged out", av[ 1 ] );
	    snet_writef( sn, "%d LOGIN: Already logged out\r\n", 505 );
	    return( 1 );
	}
	if ( strcmp( av[ 3 ], ci.ci_user ) != 0 ) {
	    syslog( LOG_ERR, "%s in cookie %s does not match %s",
		    ci.ci_user, av[ 1 ], av[ 3 ] );
	    snet_writef( sn,
		"%d user name given does not match cookie\r\n", 402 );
	    return( 1 );
	}
    }

    if ( gettimeofday( &tv, NULL ) != 0 ) {
	syslog( LOG_ERR, "f_login: gettimeofday: %m" );
	return( -1 );
    }

    if ( snprintf( tmppath, sizeof( tmppath ), "%x%x.%i",
	    (int)tv.tv_sec, (int)tv.tv_usec, (int)getpid()) >=
	    sizeof( tmppath )) {
	syslog( LOG_ERR, "f_login: tmppath too long" );
	return( -1 );
    }

    if (( fd = open( tmppath, O_CREAT|O_EXCL|O_WRONLY, 0644 )) < 0 ) {
	syslog( LOG_ERR, "f_login: open: %s: %m", tmppath );
	return( -1 );
    }

    if (( tmpfile = fdopen( fd, "w" )) == NULL ) {
	/* close */
	if ( unlink( tmppath ) != 0 ) {
	    syslog( LOG_ERR, "f_login: unlink: %m" );
	}
	syslog( LOG_ERR, "f_login: fdopen: %m" );
	return( -1 );
    }

    fprintf( tmpfile, "v2\n" );
    fprintf( tmpfile, "s1\n" );	 /* 1 is logged in, 0 is logged out */

    if ( strlen( av[ 2 ] ) >= sizeof( ci.ci_ipaddr )) {
	goto file_err;
    }
    if ( addinfo ) {
	fprintf( tmpfile, "i%s\n", ci.ci_ipaddr );
    } else {
	fprintf( tmpfile, "i%s\n", av[ 2 ] );
    }

    if ( addinfo ) {
	if ( strcmp( ci.ci_ipaddr_cur, av[ 2 ] ) != 0 ) {
	    newinfo = 1;
	}
    }
    if ( strlen( av[ 2 ] ) >= sizeof( ci.ci_ipaddr_cur )) {
	goto file_err;
    }
    fprintf( tmpfile, "j%s\n", av[ 2 ] );

    if ( strlen( av[ 3 ] ) >= sizeof( ci.ci_user )) {
	goto file_err;
    }
    fprintf( tmpfile, "p%s\n", av[ 3 ] );
    if ( strlen( av[ 4 ] ) >= sizeof( ci.ci_realm )) {
	goto file_err;
    }

    if ( addinfo ) {
	if (( facav = acav_alloc()) == NULL ) {
	    syslog( LOG_ERR, "acav_alloc: %m" );
	    goto file_err;
	}
	if (( fc = acav_parse( facav, ci.ci_realm, &fv )) < 0 ) {
	    syslog( LOG_ERR, "acav_parse: %m" );
	    goto file_err;
	}
	fprintf( tmpfile, "r%s", fv[ 0 ] );
	for ( i = 1; i < fc; i++ ) {
	    fprintf( tmpfile, " %s", fv[ i ] );
	}
	for ( i = 4; i < ac; i++ ) {
	    for ( j = 0; j < fc; j++ ) {
		if ( strcmp( fv[ j ], av[ i ] ) == 0 ) {
		    break;
		}
	    }
	    if ( j >= fc ) {
		fprintf( tmpfile, " %s", av[ i ] );
		newinfo = 1;
	    }
	}
	if ( newinfo == 0 ) {
	    snet_writef( sn, "%d LOGIN Cookie Already Stored.\r\n", 202 );
	    if ( fclose ( tmpfile ) != 0 ) {
		syslog( LOG_ERR, "f_login: fclose: %m" );
	    }
	    if ( unlink( tmppath ) != 0 ) {
		syslog( LOG_ERR, "f_login: unlink %s: %m", tmppath );
	    }
	    return( 0 );
	}
    } else {
	fprintf( tmpfile, "r%s", av[ 4 ] );
	for ( i = 5; i < ac; i++ ) {
	    fprintf( tmpfile, " %s", av[ i ] );
	}
    }
    fprintf( tmpfile, "\n" );

    if ( addinfo ) {
	fprintf( tmpfile, "t%lu\n", ci.ci_itime);
    } else {
	fprintf( tmpfile, "t%lu\n", tv.tv_sec );
    }

    if ( krb ) {
	if (( addinfo ) && ( *ci.ci_krbtkt != '\0' )) {
	    fprintf( tmpfile, "k%s\n", ci.ci_krbtkt );
	    already_krb = 1;
	} else {
	    fprintf( tmpfile, "k%s\n", krbpath );
	}
    } else if ( *ci.ci_krbtkt != '\0' ) {
	fprintf( tmpfile, "k%s\n", ci.ci_krbtkt );
	already_krb = 1;
    }

    if ( fclose ( tmpfile ) != 0 ) {
	if ( unlink( tmppath ) != 0 ) {
	    syslog( LOG_ERR, "f_login: unlink %s: %m", tmppath );
	}
	syslog( LOG_ERR, "f_login: fclose: %m" );
	return( -1 );
    }

    if ( addinfo ) {
	if ( rename( tmppath, path ) != 0 ) {
	    syslog( LOG_ERR, "f_login: rename %s to %s: %m", tmppath, path );
	    err = -1;
	    goto file_err2;
	}
    } else {
	if ( link( tmppath, path ) != 0 ) {
	    syslog( LOG_ERR, "f_login: link %s to %s: %m", tmppath, path );
	    err = -1;
	    goto file_err2;
	}
	if ( unlink( tmppath ) != 0 ) {
	    syslog( LOG_ERR, "f_login: unlink %s: %m", tmppath );
	}
    }

    if (( !krb ) || ( already_krb )) {
	snet_writef( sn, "%d LOGIN successful: Cookie Stored.\r\n", 200 );
	if (( pushersn != NULL ) && ( !replicated )) {
	    snet_writef( pushersn, "LOGIN %s %s %s %s\r\n",
		    av[ 1 ], av[ 2 ], av[ 3 ], av[ 4 ]);
	}
	if ( !replicated ) {
	    syslog( LOG_INFO, "LOGIN %s %s %s", av[ 3 ], av [ 4 ], av [ 2 ] );
	}
	return( 0 );
    }

    snet_writef( sn, "%d LOGIN: Send length then file.\r\n", 300 );

    if (( fd = open( krbpath, O_CREAT|O_EXCL|O_WRONLY, 0644 )) < 0 ) {
	syslog( LOG_ERR, "f_login: open: %s: %m", krbpath );
	return( -1 );
    }

    tv = cosign_net_timeout;
    if (( sizebuf = snet_getline( sn, &tv )) == NULL ) {
        syslog( LOG_ERR, "f_login: snet_getline: %m" );
        return( -1 );
    }

    for ( len = atoi( sizebuf ); len > 0; len -= rc ) {
        tv = cosign_net_timeout;
        if (( rc = snet_read(
                sn, buf, (int)MIN( len, sizeof( buf )), &tv )) <= 0 ) {
            syslog( LOG_ERR, "f_login: snet_read: %m" );
            return( -1 );
        }

        if ( write( fd, buf, rc ) != rc ) {
	    syslog( LOG_ERR, "f_login: write to %s: %m", krbpath );
            snet_writef( sn, "%d %s: %s\r\n", 504, krbpath, strerror( errno ));
            return( 1 );
        }
    }

    if ( close( fd ) < 0 ) {
	syslog( LOG_ERR, "f_login: close %s: %m", krbpath );
        snet_writef( sn, "%d %s: %s\r\n", 504, krbpath, strerror( errno ));
        return( 1 );
    }


    tv = cosign_net_timeout;
    tv.tv_usec = 0;
    if (( line = snet_getline( sn, &tv )) == NULL ) {
        syslog( LOG_ERR, "f_login: snet_getline: %m" );
        return( -1 );
    }

    /* make sure client agrees we're at the end */
    if ( strcmp( line, "." ) != 0 ) {
        snet_writef( sn, "%d Length doesn't match sent data\r\n", 505 );
        (void)unlink( krbpath );

	/* if the krb tkt didn't store, unlink the cookie as well */
	if ( unlink( av[ 1 ] ) != 0 ) {
	    syslog( LOG_ERR, "f_login: unlink: %m" );
	}

        tv = cosign_net_timeout;
        tv.tv_usec = 0;
        for (;;) {
            if (( line = snet_getline( sn, &tv )) == NULL ) {
                syslog( LOG_ERR, "f_login: snet_getline: %m" );
                exit( 1 );
            }
            if ( strcmp( line, "." ) == 0 ) {
                break;
            }
        }
        exit( 1 );
    }


    snet_writef( sn, "%d LOGIN successful: Cookie & Ticket Stored.\r\n", 201 );
    if (( pushersn != NULL ) && ( !replicated )) {
	snet_writef( pushersn, "LOGIN %s %s %s %s %s\r\n",
		av[ 1 ], av[ 2 ], av[ 3 ], av[ 4 ], av[ 5 ]);
    }
    if ( !replicated ) {
	syslog( LOG_INFO, "LOGIN %s %s %s", av[ 3 ], av [ 4 ], av [ 2 ] );
    }
    return( 0 );

file_err:
    (void)fclose( tmpfile );
    if ( unlink( tmppath ) != 0 ) {
	syslog( LOG_ERR, "f_login: unlink: %m" );
    }
    syslog( LOG_ERR, "f_login: bad file format" );
    snet_writef( sn, "%d LOGIN Syntax Error: Bad File Format\r\n", 504 );
    return( 1 );

file_err2:
    if ( unlink( tmppath ) != 0 ) {
	syslog( LOG_ERR, "f_login: unlink: %m" );
    }
    return( err );
}
示例#8
0
    int
f_retr( SNET *sn, int ac, char *av[], SNET *pushersn )
{
    struct servicelist	*sl;
    struct cinfo        ci;
    struct timeval      tv;
    char		lpath[ MAXPATHLEN ], spath[ MAXPATHLEN ];
    char		login[ MAXCOOKIELEN ];

    if (( al->al_key != CGI ) && ( al->al_key != SERVICE )) {
	syslog( LOG_ERR, "f_retr: %s not allowed", al->al_hostname );
	snet_writef( sn, "%d RETR: %s not allowed to retrieve.\r\n",
		442, al->al_hostname );
	return( 1 );
    }

    if ( ac != 3 ) {
	syslog( LOG_ERR, "f_retr: %s Wrong number of args.", al->al_hostname );
	snet_writef( sn, "%d RETR: Wrong number of args.\r\n", 540 );
	return( 1 );
    }

    if (( sl = service_valid( av[ 1 ] )) == NULL ) {
	snet_writef( sn, "%d RETR: Invalid cookie\r\n", 545 );
	return( 1 );
    }

    if ( mkcookiepath( NULL, hashlen, av[ 1 ], spath, sizeof( spath )) < 0 ) {
	syslog( LOG_ERR, "f_retr: mkcookiepath error" );
	snet_writef( sn, "%d RETR: Invalid cookie name.\r\n", 541 );
	return( 1 );
    }

    if ( service_to_login( spath, login ) != 0 ) {
	snet_writef( sn, "%d RETR: cookie not in db!\r\n", 543 );
	return( 1 );
    }

    if ( mkcookiepath( NULL, hashlen, login, lpath, sizeof( lpath )) < 0 ) {
	syslog( LOG_ERR, "f_retr: mkcookiepath error" );
	snet_writef( sn, "%d RETR: Invalid cookie name.\r\n", 541 );
	return( 1 );
    }

    if ( read_cookie( lpath, &ci ) != 0 ) {
	snet_writef( sn, "%d RETR: Who me? Dunno.\r\n", 544 );
	return( 1 );
    }

    if ( ci.ci_state == 0 ) {
	snet_writef( sn, "%d RETR: Already logged out\r\n", 440 );
	return( 1 );
    }

    /* check for idle timeout, and if so, log'em out */
    if ( gettimeofday( &tv, NULL ) != 0 ){
	syslog( LOG_ERR, "f_retr: gettimeofday: %m" );
	return( -1 );
    }

    if ( tv.tv_sec - ci.ci_itime >= idle_out_time ) {
	if ( tv.tv_sec - ci.ci_itime < ( idle_out_time + grey_time )) {
	    syslog( LOG_ERR, "f_retr: idle grey window" );
	    snet_writef( sn, "%d RETR: Idle Grey Window\r\n", 541 );
	    return( 1 );
	}
	snet_writef( sn, "%d RETR: Idle logged out\r\n", 441 );
	if ( do_logout( lpath ) < 0 ) {
	    syslog( LOG_ERR, "f_retr: %s: %m", login );
	    return( -1 );
	}
	return( 1 );
    }

    if ( strcmp( av[ 2 ], "tgt") == 0 ) {
	return( retr_ticket( sn, sl, ci.ci_krbtkt ));
    } else if ( strcmp( av[ 2 ], "cookies") == 0 ) {
	return( retr_proxy( sn, login, pushersn ));
    }

    syslog( LOG_ERR, "f_retr: no such retrieve type: %s", av[ 1 ] );
    snet_writef( sn, "%d RETR: No such retrieve type.\r\n", 441 );
    return( 1 );
}
示例#9
0
int
main (int argc, char *argv[])
{
  int rc;
  const char *user_to_auth;
  char *cookie = NULL;
  struct pam_conv pam_conversation;
  pam_handle_t *pam_h;
  const void *authed_user;

  rc = 0;
  pam_h = NULL;

  /* clear the entire environment to avoid attacks using with libraries honoring environment variables */
  if (_polkit_clearenv () != 0)
    goto error;

  /* set a minimal environment */
  setenv ("PATH", "/usr/sbin:/usr/bin:/sbin:/bin", 1);

  /* check that we are setuid root */
  if (geteuid () != 0)
    {
      gchar *s;

      fprintf (stderr, "polkit-agent-helper-1: needs to be setuid root\n");

      /* Special-case a very common error triggered in jhbuild setups */
      s = g_strdup_printf ("Incorrect permissions on %s (needs to be setuid root)", argv[0]);
      send_to_helper ("PAM_ERROR_MSG", s);
      g_free (s);
      goto error;
    }

  openlog ("polkit-agent-helper-1", LOG_CONS | LOG_PID, LOG_AUTHPRIV);

  /* check for correct invocation */
  if (!(argc == 2 || argc == 3))
    {
      syslog (LOG_NOTICE, "inappropriate use of helper, wrong number of arguments [uid=%d]", getuid ());
      fprintf (stderr, "polkit-agent-helper-1: wrong number of arguments. This incident has been logged.\n");
      goto error;
    }

  user_to_auth = argv[1];

  cookie = read_cookie (argc, argv);
  if (!cookie)
    goto error;

  if (getuid () != 0)
    {
      /* check we're running with a non-tty stdin */
      if (isatty (STDIN_FILENO) != 0)
        {
          syslog (LOG_NOTICE, "inappropriate use of helper, stdin is a tty [uid=%d]", getuid ());
          fprintf (stderr, "polkit-agent-helper-1: inappropriate use of helper, stdin is a tty. This incident has been logged.\n");
          goto error;
        }
    }

#ifdef PAH_DEBUG
  fprintf (stderr, "polkit-agent-helper-1: user to auth is '%s'.\n", user_to_auth);
#endif /* PAH_DEBUG */

  pam_conversation.conv        = conversation_function;
  pam_conversation.appdata_ptr = NULL;

  /* start the pam stack */
  rc = pam_start ("polkit-1",
                  user_to_auth,
                  &pam_conversation,
                  &pam_h);
  if (rc != PAM_SUCCESS)
    {
      fprintf (stderr, "polkit-agent-helper-1: pam_start failed: %s\n", pam_strerror (pam_h, rc));
      goto error;
    }

  /* set the requesting user */
  rc = pam_set_item (pam_h, PAM_RUSER, user_to_auth);
  if (rc != PAM_SUCCESS)
    {
      fprintf (stderr, "polkit-agent-helper-1: pam_set_item failed: %s\n", pam_strerror (pam_h, rc));
      goto error;
    }

  /* is user really user? */
  rc = pam_authenticate (pam_h, 0);
  if (rc != PAM_SUCCESS)
    {
      const char *err;
      err = pam_strerror (pam_h, rc);
      fprintf (stderr, "polkit-agent-helper-1: pam_authenticate failed: %s\n", err);
      goto error;
    }

  /* permitted access? */
  rc = pam_acct_mgmt (pam_h, 0);
  if (rc != PAM_SUCCESS)
    {
      const char *err;
      err = pam_strerror (pam_h, rc);
      fprintf (stderr, "polkit-agent-helper-1: pam_acct_mgmt failed: %s\n", err);
      goto error;
    }

  /* did we auth the right user? */
  rc = pam_get_item (pam_h, PAM_USER, &authed_user);
  if (rc != PAM_SUCCESS)
    {
      const char *err;
      err = pam_strerror (pam_h, rc);
      fprintf (stderr, "polkit-agent-helper-1: pam_get_item failed: %s\n", err);
      goto error;
    }

  if (strcmp (authed_user, user_to_auth) != 0)
    {
      fprintf (stderr, "polkit-agent-helper-1: Tried to auth user '%s' but we got auth for user '%s' instead",
               user_to_auth, (const char *) authed_user);
      goto error;
    }

#ifdef PAH_DEBUG
  fprintf (stderr, "polkit-agent-helper-1: successfully authenticated user '%s'.\n", user_to_auth);
#endif /* PAH_DEBUG */

  pam_end (pam_h, rc);
  pam_h = NULL;

#ifdef PAH_DEBUG
  fprintf (stderr, "polkit-agent-helper-1: sending D-Bus message to PolicyKit daemon\n");
#endif /* PAH_DEBUG */

  /* now send a D-Bus message to the PolicyKit daemon that
   * includes a) the cookie; and b) the user we authenticated
   */
  if (!send_dbus_message (cookie, user_to_auth))
    {
#ifdef PAH_DEBUG
      fprintf (stderr, "polkit-agent-helper-1: error sending D-Bus message to PolicyKit daemon\n");
#endif /* PAH_DEBUG */
      goto error;
    }

  free (cookie);

#ifdef PAH_DEBUG
  fprintf (stderr, "polkit-agent-helper-1: successfully sent D-Bus message to PolicyKit daemon\n");
#endif /* PAH_DEBUG */

  fprintf (stdout, "SUCCESS\n");
  flush_and_wait();
  return 0;

error:
  free (cookie);
  if (pam_h != NULL)
    pam_end (pam_h, rc);

  fprintf (stdout, "FAILURE\n");
  flush_and_wait();
  return 1;
}