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