コード例 #1
0
ファイル: UploadOperation.cpp プロジェクト: sim0629/tightvnc
UINT64 UploadOperation::getFileSize(const TCHAR *pathToFile)
{
    UINT64 fileSize = 0;

    File file(pathToFile);

    if (file.isDirectory()) {
        UINT32 filesCount = 0;
        file.list(NULL, &filesCount);

        StringStorage *fileNames = new StringStorage[filesCount];
        file.list(fileNames, NULL);

        for (UINT32 i = 0; i < filesCount; i++) {
            File subfile(pathToFile, fileNames[i].getString());

            StringStorage pathToSubFile;
            subfile.getPath(&pathToSubFile);

            fileSize += getFileSize(pathToSubFile.getString());
        }

        delete[] fileNames;
    } else {
        INT64 len = file.length();
        if (len == -1) {
            fileSize = 0;
        } else {
            fileSize = (UINT64)len;
        }
    }

    return fileSize;
}
コード例 #2
0
ファイル: File.cpp プロジェクト: onze/Steel
    std::vector<File> File::ls(File::NodeType filter, bool include_hidden) const
    {
        if(!(exists() && isDir()))
            return std::vector<File>(0);

        std::vector<std::string> files;
        Poco::File(fullPath()).list(files);

        std::list<File> nodes;

        for(auto it = files.begin(); it != files.end(); ++it)
        {
            File file = subfile(*it);
            NodeType nodeType = file.nodeType();

            if(nodeType & filter)
            {
                if(!include_hidden && (nodeType & HIDDEN))
                    continue;

                nodes.push_back(file);
            }
        }

        std::vector<File> vecnodes;

        for(auto it = nodes.begin(); it != nodes.end(); ++it)
            vecnodes.push_back(*it);

        return vecnodes;
    }
コード例 #3
0
bool FileTransferRequestHandler::getDirectorySize(const TCHAR *pathname, UINT64 *dirSize)
{
  UINT64 currentDirSize = 0;
  UINT32 filesCount = 0;
  UINT32 dataSize = 0;

  File folder(pathname);

  //
  // Get files count
  //

  if (!folder.list(NULL, &filesCount)) {
    return false;
  }

  if (filesCount != 0) {
    std::vector<StringStorage> fileNames(filesCount);

    //
    // Get file names
    //

    folder.list(&fileNames.front(), NULL);

    for (UINT32 i = 0; i < filesCount; i++) {
      File subfile(pathname, fileNames[i].getString());
      if (subfile.isDirectory()) {

        UINT64 subDirSize = 0;
        StringStorage subDirPath;

        subfile.getPath(&subDirPath);

        if (getDirectorySize(subDirPath.getString(), &subDirSize)) {
          currentDirSize += subDirSize;
        }  // if it got sub directory size
      } else {
        currentDirSize += subfile.length();
      } // if subfile is normal file
    } // for every subfile in file list
  }
  *dirSize = currentDirSize;

  return true;
}
コード例 #4
0
ファイル: File.cpp プロジェクト: onze/Steel
 File File::operator/(Ogre::String const filename) const
 {
     return subfile(filename);
 }
コード例 #5
0
ファイル: login.c プロジェクト: ossxp-com/cosign-ossxp-hacks
    int
cosign_login_krb5( struct connlist *head, char *cosignname, char *id, 
	char *realm, char *passwd, char *ip_addr, char *cookie, 
	struct subparams *sp, char **msg )
{
    krb5_error_code             kerror = 0;
    krb5_context                kcontext;
    krb5_principal              kprinc;
    krb5_principal              sprinc;
    krb5_get_init_creds_opt     kopts;
    krb5_verify_init_creds_opt 	kvic_opts[ 1 ];
    krb5_creds                  kcreds;
    krb5_ccache                 kccache;
    krb5_keytab                 keytab = 0;
    char			*tmpl = ERROR_HTML; 
    char			*sprinc_name = NULL;
    char                        ktbuf[ MAX_KEYTAB_NAME_LEN + 1 ];
    char                        tmpkrb[ 16 ], krbpath [ MAXPATHLEN ];
    int				i;

    lcgi_configure();

    if (( kerror = krb5_init_context( &kcontext ))) {
	sl[ SL_ERROR ].sl_data = (char *)error_message( kerror );
	sl[ SL_TITLE ].sl_data = "Authentication Required ( kerberos error )";
	subfile( tmpl, sl, 0 );
	exit( 0 );
    }

    if (( kerror = krb5_parse_name( kcontext, id, &kprinc ))) {
	sl[ SL_ERROR ].sl_data = (char *)error_message( kerror );
	sl[ SL_TITLE ].sl_data = "Authentication Required ( kerberos error )";
	subfile( tmpl, sl, 0 );
	exit( 0 );
    }

    /* need to get realm out */
    if ( realm == NULL || *realm == '\0' ) {
	if (( kerror = krb5_get_default_realm( kcontext, &realm )) != 0 ) {
	    sl[ SL_ERROR ].sl_data = (char *)error_message( kerror );
 	    sl[ SL_TITLE ].sl_data = "Authentication Required "
		    "( krb realm error )";
	    subfile( tmpl, sl, 0 );
	    exit( 0 );
    	}
    }

    if ( store_tickets ) {
	if ( mkcookie( sizeof( tmpkrb ), tmpkrb ) != 0 ) {
	    sl[ SL_ERROR ].sl_data = "An unknown error occurred.";
	    sl[ SL_TITLE ].sl_data = "Authentication Required (kerberos error)";
	    subfile( tmpl, sl, 0 );
	    exit( 0 );
	}

	if ( snprintf( krbpath, sizeof( krbpath ), "%s/%s",
		ticket_path, tmpkrb ) >= sizeof( krbpath )) {
	    sl[ SL_ERROR ].sl_data = "An unknown error occurred.";
	    sl[ SL_TITLE ].sl_data = "Authentication Required (krbpath error)";
	    subfile( tmpl, sl, 0 );
	    exit( 0 );
	}

	if (( kerror = krb5_cc_resolve( kcontext, krbpath, &kccache )) != 0 ) {
	    sl[ SL_ERROR ].sl_data = (char *)error_message( kerror );
	    sl[ SL_TITLE ].sl_data = "Authentication Required (kerberos error)";
	    subfile( tmpl, sl, 0 );
	    exit( 0 );
	}
    }

    krb5_get_init_creds_opt_init( &kopts );
    krb5_get_init_creds_opt_set_tkt_life( &kopts, tkt_life );
    krb5_get_init_creds_opt_set_renew_life( &kopts, 0 );
    krb5_get_init_creds_opt_set_forwardable( &kopts, 1 );
    krb5_get_init_creds_opt_set_proxiable( &kopts, 0 );

    if (( kerror = krb5_get_init_creds_password( kcontext, &kcreds, 
	    kprinc, passwd, NULL, NULL, 0, NULL /*keytab */, &kopts ))) {

	if (( kerror == KRB5KRB_AP_ERR_BAD_INTEGRITY ) ||
		( kerror == KRB5KDC_ERR_PREAUTH_FAILED ) ||
		( kerror == KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN )) {
	    return( COSIGN_CGI_ERROR );	/* draw login or reauth page */
        } else if ( kerror == KRB5KDC_ERR_KEY_EXP ) {
	    *msg = (char *)error_message( kerror );
            return( COSIGN_CGI_PASSWORD_EXPIRED );
	} else {
	    sl[ SL_ERROR ].sl_data = (char *)error_message( kerror );
	    sl[ SL_TITLE ].sl_data = "Error";
	    subfile( tmpl, sl, 0 );
	    exit( 0 );
	}
    }

    /* verify no KDC spoofing */
    if ( *keytab_path != '\0' ) {
	if ( strlen( keytab_path ) > MAX_KEYTAB_NAME_LEN ) {
	    sl[ SL_ERROR ].sl_data = "server configuration error";
	    sl[ SL_TITLE ].sl_data = "Ticket Verification Error";
	    subfile( tmpl, sl, 0 );
	    exit( 0 );
	}
	strcpy( ktbuf, keytab_path );

	/* from mdw */
	krb5_verify_init_creds_opt_init( kvic_opts );
	krb5_verify_init_creds_opt_set_ap_req_nofail( kvic_opts, 1 );

	if (( kerror = krb5_kt_resolve( kcontext, ktbuf, &keytab )) != 0 ) {
	    sl[ SL_ERROR ].sl_data = (char *)error_message( kerror );
	    sl[ SL_TITLE ].sl_data = "KT Resolve Error";
	    subfile( tmpl, sl, 0 );
	    exit( 0 );
	}

	if ( cosign_princ ) {
	    kerror = krb5_parse_name( kcontext, cosign_princ, &sprinc );
	} else {
	    kerror = krb5_sname_to_principal( kcontext, NULL, "cosign",
			KRB5_NT_SRV_HST, &sprinc );
	}
	if ( kerror != 0 ) {
	    sl[ SL_ERROR ].sl_data = (char *)error_message( kerror );
	    sl[ SL_TITLE ].sl_data = "Server Principal Error";
	    subfile( tmpl, sl, 0 );
	    exit( 0 );
	}

	if (( kerror = krb5_verify_init_creds(
		kcontext, &kcreds, sprinc, keytab, NULL, kvic_opts )) != 0 ) {
	    if ( krb5_unparse_name( kcontext, sprinc, &sprinc_name ) == 0 ) {
		fprintf( stderr, "ticket verify error for "
			 "user %s, keytab principal %s", id, sprinc_name );
		free( sprinc_name );
	    } else {
		fprintf( stderr, "ticket verify error for user %s", id );
	    }
	    sl[ SL_ERROR ].sl_data = (char *)error_message( kerror );
	    sl[ SL_TITLE ].sl_data = "Ticket Verify Error";
	    subfile( tmpl, sl, 0 );
	    krb5_free_principal( kcontext, sprinc );
	    exit( 0 );
	}
	(void)krb5_kt_close( kcontext, keytab );
	krb5_free_principal( kcontext, sprinc );
    }

    for ( i = 0; i < COSIGN_MAXFACTORS - 1; i++ ) {
	if ( new_factors[ i ] == NULL ) {
	    new_factors[ i ] = strdup( realm );
	    new_factors[ i + 1 ] = NULL;
	    break;
	}
	if ( strcmp( new_factors[ i ], realm ) == 0 ) {
	    break;
	}
    }

    if ( sp->sp_reauth && sp->sp_ipchanged == 0 ) {
	return( COSIGN_CGI_OK );
    }

    if ( store_tickets ) {
	if (( kerror = krb5_cc_initialize( kcontext, kccache, kprinc )) != 0 ) {
	    sl[ SL_ERROR ].sl_data = (char *)error_message( kerror );
	    sl[ SL_TITLE ].sl_data = "CC Initialize Error";
	    subfile( tmpl, sl, 0 );
	    exit( 0 );
	}
	if (( kerror = krb5_cc_store_cred( kcontext, kccache, &kcreds ))
		!= 0 ) {
	    sl[ SL_ERROR ].sl_data = (char *)error_message( kerror );
	    sl[ SL_TITLE ].sl_data = "CC Storing Error";
	    subfile( tmpl, sl, 0 );
	    exit( 0 );
	}
	krb5_cc_close( kcontext, kccache );
    }

    krb5_free_cred_contents( kcontext, &kcreds );
    krb5_free_principal( kcontext, kprinc );
    krb5_free_context( kcontext );

    /* password has been accepted, tell cosignd */
    if ( cosign_login( head, cookie, ip_addr, cosignname, realm, 
	    ( store_tickets ? krbpath : NULL )) < 0 ) {
	fprintf( stderr, "cosign_login_krb5: login failed\n") ;
	sl[ SL_ERROR ].sl_data = "We were unable to contact the "
		"authentication server. Please try again later.";
	sl[ SL_TITLE ].sl_data = "Error: Please try later";
	subfile( tmpl, sl, 0 );
	exit( 0 );
    }

    return( COSIGN_CGI_OK );
}
コード例 #6
0
ファイル: login.c プロジェクト: ossxp-com/cosign-ossxp-hacks
    int
cosign_login_mysql( struct connlist *head, char *cosignname, char *id, 
	char *realm, char *passwd, char *ip_addr, char *cookie, 
	struct subparams *sp, char **msg )
{
    MYSQL_RES		*res;
    MYSQL_ROW		row;
    char		sql[ 225 ]; /* holds sql query + email addr */
    char		*crypted, *p;
    char		*tmpl = ERROR_HTML; 
    int			i;

    lcgi_configure();

    if ( !mysql_real_connect( &friend_db, friend_db_name, friend_login, friend_passwd, "friend", 3306, NULL, 0 )) {
	fprintf( stderr, mysql_error( &friend_db ));
	sl[ SL_ERROR ].sl_data = "Unable to connect to guest account database.";
	sl[ SL_TITLE ].sl_data = "Database Problem";
	subfile( tmpl, sl, 0 );
	exit( 0 );
    }

    /* Check for sql injection prior to username query */
    for ( p = id; *p != '\0'; p++ ) {
	if (( isalpha( *p ) != 0 ) || (isdigit( *p ) != 0 )) {
	    continue;
	}

	switch ( *p ) {
	case '@':
	case '_':
	case '-':
	case '.':
	    continue;

	default:
	    fprintf( stderr, "invalid username: %s %s\n", id, ip_addr );
	    sl[ SL_ERROR ].sl_data = "Provided login appears to be invalid";
	    sl[ SL_TITLE ].sl_data = "Invalid Input";
	    subfile( tmpl, sl, 0 );
	    exit( 0 );
	}
    }
    if ( snprintf( sql, sizeof( sql ), "SELECT login, passwd"
	    " FROM friend WHERE login = '******' AND passwd is NOT NULL",
	    id ) >= sizeof( sql )) {
	fprintf( stderr, "invalid username: %s %s\n", id, ip_addr );
	sl[ SL_ERROR ].sl_data = "Provided login appears to be invalid";
	sl[ SL_TITLE ].sl_data = "Invalid Input";
	subfile( tmpl, sl, 0 );
	exit( 0 );
    }

    if( mysql_real_query( &friend_db, sql, strlen( sql ))) {
	fprintf( stderr, mysql_error( &friend_db ));
	sl[ SL_ERROR ].sl_data = "Unable to query guest account database.";
	sl[ SL_TITLE ].sl_data = "Server Problem";
	subfile( tmpl, sl, 0 );
	exit( 0 );
    }

    if (( res = mysql_store_result( &friend_db )) == NULL ) {
	/* was there an error?  NULL can be okay. */
	if ( mysql_errno( &friend_db )) {
	    fprintf( stderr, mysql_error( &friend_db ));
	    sl[ SL_ERROR ].sl_data = "Problems connecting to the database.";
	    sl[ SL_TITLE ].sl_data = "Database Connection Problem";
	    subfile( tmpl, sl, 0 );
	    exit( 0 );
	}
    }

    if (( row = mysql_fetch_row( res )) == NULL ) {
	return( COSIGN_CGI_ERROR );
    }

    /* crypt the user's password */
    crypted = crypt( passwd, row[ 1 ] );

    if ( strcmp( crypted, row[ 1 ] ) != 0 ) {
	mysql_free_result( res );
	mysql_close( &friend_db );

	/* this is a valid friend account but password failed */
	return( COSIGN_CGI_ERROR );
    }

    mysql_free_result( res );
    mysql_close( &friend_db );

    for ( i = 0; i < COSIGN_MAXFACTORS - 1; i++ ) {
	if ( new_factors[ i ] == NULL ) {
	    new_factors[ i ] = "friend";
	    new_factors[ i + 1 ] = NULL;
	    break;
	}
	if ( strcmp( new_factors[ i ], "friend" ) == 0 ) {
	    break;
	}
    }

    if ( sp->sp_reauth && sp->sp_ipchanged == 0 ) {
	return( COSIGN_CGI_OK );
    }

    if ( cosign_login( head, cookie, ip_addr, cosignname, realm, NULL ) < 0 ) {
	fprintf( stderr, "cosign_login_mysql: login failed\n" ) ;
	sl[ SL_ERROR ].sl_data = "We were unable to contact the "
		"authentication server. Please try again later.";
	sl[ SL_TITLE ].sl_data = "Error: Please try later";
	subfile( tmpl, sl, 0 );
	exit( 0 );
    }
    return( COSIGN_CGI_OK );
}
コード例 #7
0
PSFTags PSFLoader::LoadInternal(uint8 version, uint32 max_exe_size, MDFNFILE *fp, uint32 level, bool force_ignore_pcsp)
{
 uint32 reserved_size, compressed_size, compressed_crc32;
 bool _lib_present = false;
 PSFTags tags;

 std::vector<uint8> decompress_buffer;
 uLongf decompress_len;

 if(!TestMagic(version, fp))
  throw(MDFN_Error(0, _("Not a PSF(version=0x%02x) file!"), version));

 reserved_size = MDFN_de32lsb(fp->data + 4);
 compressed_size = MDFN_de32lsb(fp->data + 8);
 compressed_crc32 = MDFN_de32lsb(fp->data + 12);

 if(fp->size < (16 + reserved_size + compressed_size))
  throw(MDFN_Error(0, _("PSF is missing at least %u bytes of data!"), 16 + reserved_size + compressed_size - fp->size));

 if(crc32(0, fp->data + 16 + reserved_size, compressed_size) != compressed_crc32)
  throw(MDFN_Error(0, _("PSF compressed CRC32 mismatch(data is corrupt)!")));


 {
  const uint8 *tag_section = fp->data + 16 + reserved_size + compressed_size;
  uint32 tag_section_size = fp->size - 16 - reserved_size - compressed_size;

  if(tag_section_size > 5 && !memcmp(tag_section, "[TAG]", 5))
   tags.LoadTags(tag_section + 5, tag_section_size - 5);
 }

 //
 // Handle minipsf simple _lib
 //

 if(level < 15)
 {
  if(tags.TagExists("_lib"))
  {
   std::string tp = tags.GetTag("_lib");

   if(!MDFN_IsFIROPSafe(tp))
   {
    throw(MDFN_Error(0, _("Referenced path \"%s\" is potentially unsafe.  See \"filesys.untrusted_fip_check\" setting."), tp.c_str()));
   }

   MDFNFILE subfile(MDFN_MakeFName(MDFNMKF_AUX, 0, tp.c_str()).c_str(), NULL, NULL);

   LoadInternal(version, max_exe_size, &subfile, level + 1);

   _lib_present = true;
  }
 }

 //
 //
 //

 decompress_buffer.resize(max_exe_size);
 decompress_len = max_exe_size;
 switch( uncompress((Bytef *)&decompress_buffer[0], &decompress_len, (const Bytef *)(fp->data + 16 + reserved_size), compressed_size) )
 {
  default:
	throw(MDFN_Error(0, "zlib unknown error"));

  case Z_OK: break;

  case Z_MEM_ERROR:
	throw(MDFN_Error(0, "zlib Z_MEM_ERROR"));

  case Z_BUF_ERROR:
	throw(MDFN_Error(0, _("PSF decompressed size exceeds maximum allowed!")));

  case Z_DATA_ERROR:
	throw(MDFN_Error(0, _("PSF compressed data is bad.")));
 }

 HandleReserved(fp->data + 16, reserved_size);
 HandleEXE(&decompress_buffer[0], decompress_len, force_ignore_pcsp | _lib_present);
 decompress_buffer.resize(0);

 //
 // handle libN
 //
 if(level < 15)
 {
  for(unsigned int n = 2; n <= INT_MAX; n++)
  {
   char tmpbuf[32];

   trio_snprintf(tmpbuf, 32, "_lib%d", (int)n);

   if(tags.TagExists(tmpbuf))
   {
    MDFNFILE subfile(MDFN_MakeFName(MDFNMKF_AUX, 0, tags.GetTag(tmpbuf).c_str()).c_str(), NULL, NULL);

    LoadInternal(version, max_exe_size, &subfile, level + 1, true);
   }
   else
    break;   
  }
 }

 return(tags);
}
コード例 #8
0
ファイル: logout.c プロジェクト: JorjBauer/cosign
    int
main( int argc, char *argv[] )
{
    CGIHANDLE		*cgi;
    char		*tmpl = VERIFY_LOGOUT;
    char		*cookie = NULL, *data, *ip_addr, *qs;
    char		*method = NULL;
    struct connlist	*head;
    char		*script;

    if ( argc == 2 && ( strncmp( argv[ 1 ], "-V", 2 ) == 0 )) {
	printf( "%s\n", cosign_version );
	exit( 0 );
    }

    if (( cosign_conf = getenv( "COSIGN_CGI_CONF" )) == NULL ) {
	cosign_conf = _COSIGN_CONF;
    }

    if ( cosign_config( cosign_conf ) < 0 ) {
	fprintf( stderr, "Couldn't read %s\n", cosign_conf );
        exit( 1 );
    }
    logout_configure();
    if ( chdir( tmpldir ) < 0 ) {
	perror( tmpldir );
	exit( 1 );
    }

    if (( ip_addr = getenv( "REMOTE_ADDR" )) == NULL ) {
        sl[ SL_TITLE ].sl_data = "Error: Server Error";
        sl[ SL_ERROR ].sl_data = "REMOTE_ADDR not set";
        tmpl = ERROR_HTML;
        subfile( tmpl, sl, 0 );
	exit( 0 );
    }

    if (( script = getenv( "SCRIPT_NAME" )) == NULL ) {
        sl[ SL_TITLE ].sl_data = "Error: Server Error";
        sl[ SL_ERROR ].sl_data = "SCRIPT_NAME not set";
        tmpl = ERROR_HTML;
        subfile( tmpl, sl, 0 );
	exit( 0 );
    }

    if (( method = getenv( "REQUEST_METHOD" )) == NULL ) {
	sl[ SL_TITLE ].sl_data = "Error: Server Error";
        sl[ SL_ERROR ].sl_data = "REQUEST_METHOD not set";
	tmpl = ERROR_HTML;
	subfile( tmpl, sl, 0 );
	exit( 0 );
    }

    if ( strcmp( method, "GET" ) == 0 ) {
	/* this is not a POST, display verify screen */
	if ((( qs = getenv( "QUERY_STRING" )) != NULL ) &&
		( *qs != '\0' ) &&
		( strncmp( qs, "http", 4 ) == 0 )) {
	    /* query string looks like a url, preserve it */

	    if ( logout_url_check( qs ) == 0 ) {
		/*
		 * url matches admin-defined safe redirect URL pattern.
		 * we don't really care if strdup fails here, as subfile
		 * will do the right thing and skip the URL substitution
		 * if sl_data is NULL. sl_data is not freed because we
		 * exit immediately.
		 */
		sl[ SL_URL ].sl_data = strdup( qs );
	    }
	    /* if url check fails, default logout URL will be used */
	}

	sl[ SL_TITLE ].sl_data = "Logout Requested";
	subfile ( tmpl, sl, 0 );
	exit( 0 );
    }

    if (( cgi = cgi_init()) == NULL ){
        sl[ SL_TITLE ].sl_data = "Error: Server Error";
        sl[ SL_ERROR ].sl_data = "cgi_init failed";
        tmpl = ERROR_HTML;
        subfile( tmpl, sl, 0 );
	exit( 0 );
    }

    if ( cgi_post( cgi, cl ) != 0 ) {
	/* an actual logout must be the result of a POST, see? */
        fprintf( stderr, "%s: cgi_post failed\n", script );
        exit( 1 );
    }

    if ( cl[ CL_URL ].cl_data != NULL ) {
	/* oh the places you'll go */
        if ( strncmp( cl[ CL_URL ].cl_data, "http", 4 ) == 0 ) {
	    if ( logout_url_check( cl[ CL_URL ].cl_data ) == 0 ) {
		sl[ SL_URL ].sl_data = cl[ CL_URL ].cl_data;
	    }
	}
    }

    /*
     * Check that the 'Verify' post was sent.  If not, display the verify
     * screen again.
     */
    if ( cl[ CL_VERIFY ].cl_data == NULL ) {
	sl[ SL_TITLE ].sl_data = "Logout Requested (again?)";
	subfile ( tmpl, sl, 0 );
	exit( 0 );
    }

    /* read user's cosign cookie and LOGOUT */
    if (( data = getenv( "HTTP_COOKIE" )) != NULL ) {
        cookie = strtok( data, ";" );
        if ( cookie != NULL && strncmp( cookie, "cosign=", 7 ) != 0 ) {
            while (( cookie = strtok( NULL, ";" )) != NULL ) {
                if ( *cookie == ' ' ) ++cookie;
                if ( strncmp( cookie, "cosign=", 7 ) == 0 ) {
                    break;
                }
            }
        }
    }
    /* only the cosign= cookie and not the loop breaking info */
    if ( cookie != NULL ) (void)strtok( cookie, "/" );

    /* clobber the cosign cookie */
    fputs( "Expires: Mon, 16 Apr 1973 13:10:00 GMT\n"
	    "Last-Modified: Mon, 16 Apr 1973 13:10:00 GMT\n"
	    "Cache-Control: no-store, no-cache, must-revalidate\n"
	    "Cache-Control: pre-check=0, post-check=0, max-age=0\n"
	    "Pragma: no-cache\n", stdout );

    fputs( "Set-Cookie: cosign=null; path=/; expires=Wednesday, 16-Apr-73 02:10:00 GMT; secure\n", stdout );

    /* setup conn and ssl and hostlist to tell cosignd we're logged out */
    if (( head = connlist_setup( cosign_host, cosign_port )) == NULL ) {
        sl[ SL_TITLE ].sl_data = "Server Configuration Error";
        sl[ SL_ERROR ].sl_data = "We were unable to contact the "
		"authentication server.  Please quit your web browser "
		"to complete logout.";
        tmpl = ERROR_HTML;
        subfile( tmpl, sl, 0 );
        exit( 0 );
    }

    SSL_load_error_strings();
    SSL_library_init();

    if ( cosign_ssl( cryptofile, certfile, cadir, &ctx )) {
        sl[ SL_TITLE ].sl_data = "Server Configuration Error";
        sl[ SL_ERROR ].sl_data = "Failed to initialise connections to "
		"the authentication server. Please quit your browser to "
		"complete logout.";
        tmpl = ERROR_HTML;
        subfile( tmpl, sl, 0 );
        exit( 0 );
    }

    if ( cookie != NULL ) {
	if ( cosign_logout( head, cookie, ip_addr ) < 0 ) {
	    fprintf( stderr, "%s: logout failed\n", script ) ;

	    /* the user doesn't care that logout failed, as long as the
		cookie gets expired.  We could log user's IP and cookie
		string in the error log, but I think that's just
		useless noise so I'm going to just ignore this case
		altogether.  -- clunis
	    */
	}
    }

    printf( "Location: %s\n\n", sl[ SL_URL ].sl_data );
    exit( 0 );
}