mirror of
				https://github.com/PowerShell/Win32-OpenSSH.git
				synced 2025-10-31 11:44:38 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			277 lines
		
	
	
		
			7.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			277 lines
		
	
	
		
			7.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * Author: NoMachine <developers@nomachine.com>
 | |
|  *
 | |
|  * Copyright (c) 2009, 2011 NoMachine
 | |
|  * All rights reserved
 | |
|  *
 | |
|  * Support functions and system calls' replacements needed to let the
 | |
|  * software run on Win32 based operating systems.
 | |
|  *
 | |
|  * Redistribution and use in source and binary forms, with or without
 | |
|  * modification, are permitted provided that the following conditions
 | |
|  * are met:
 | |
|  *
 | |
|  * 1. Redistributions of source code must retain the above copyright
 | |
|  * notice, this list of conditions and the following disclaimer.
 | |
|  * 2. Redistributions in binary form must reproduce the above copyright
 | |
|  * notice, this list of conditions and the following disclaimer in the
 | |
|  * documentation and/or other materials provided with the distribution.
 | |
|  *
 | |
|  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 | |
|  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 | |
|  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 | |
|  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 | |
|  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 | |
|  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | |
|  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | |
|  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | |
|  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 | |
|  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
|  */
 | |
| 
 | |
| #include "kerberos.h"
 | |
| 
 | |
| /*
 | |
|  * Handles to runtime loaded MIT KfW libraries.
 | |
|  */
 | |
|  
 | |
| static HMODULE Krb5_32  = NULL;
 | |
| static HMODULE Comerr32 = NULL;
 | |
| static HMODULE Gssapi32 = NULL;
 | |
| 
 | |
| /*
 | |
|  * Pointers to runtime loaded KfW functions.
 | |
|  */
 | |
| 
 | |
| static struct _MitDispatch
 | |
| {
 | |
|   /*
 | |
|    * gssapi32.dll.
 | |
|    */
 | |
|    
 | |
|   gss_indicate_mechs_ptr gss_indicate_mechs;
 | |
|   gss_release_buffer_ptr gss_release_buffer;
 | |
|   gss_display_status_ptr gss_display_status;
 | |
|   gss_delete_sec_context_ptr gss_delete_sec_context;
 | |
|   gss_release_name_ptr gss_release_name;
 | |
|   gss_release_cred_ptr gss_release_cred;
 | |
|   gss_init_sec_context_ptr gss_init_sec_context;
 | |
|   gss_import_name_ptr gss_import_name;
 | |
|   gss_get_mic_ptr gss_get_mic;
 | |
| 
 | |
|   /*
 | |
|    * krb5_32.dll.
 | |
|    */
 | |
| 
 | |
|   krb5_free_context_ptr krb5_free_context;
 | |
|   krb5_free_principal_ptr krb5_free_principal;
 | |
|   krb5_cc_destroy_ptr krb5_cc_destroy;
 | |
| } MitDispatch = {0};
 | |
| 
 | |
| /*
 | |
|  * This global variable is exported by gssapi32.dll.
 | |
|  */
 | |
|  
 | |
| gss_OID gss_nt_service_name;
 | |
| 
 | |
| /*
 | |
|  * Try loads MIT Kerberos for Windows libraries. This function  
 | |
|  * must be called before use Kerberos functions.
 | |
|  *
 | |
|  * RETURNS: 0 if OK.
 | |
|  */
 | |
|  
 | |
| int InitMitKerberos()
 | |
| {
 | |
|   int exitCode = -1;
 | |
| 
 | |
|   void *serviceNamePtr = NULL;
 | |
|   
 | |
|   
 | |
|   /*
 | |
|    * Load functions from gssapi32.dll.
 | |
|    */
 | |
| 
 | |
|   debug("Loading gssapi32.dll...");
 | |
|   
 | |
|   FAIL((Gssapi32 = LoadLibrary("gssapi32.dll")) == NULL);
 | |
|   
 | |
|   FAIL((GET_MIT_FUNCTION(Gssapi32, gss_indicate_mechs)) == NULL);
 | |
|   FAIL((GET_MIT_FUNCTION(Gssapi32, gss_release_buffer)) == NULL);
 | |
|   FAIL((GET_MIT_FUNCTION(Gssapi32, gss_display_status)) == NULL);
 | |
|   FAIL((GET_MIT_FUNCTION(Gssapi32, gss_delete_sec_context)) == NULL);
 | |
|   FAIL((GET_MIT_FUNCTION(Gssapi32, gss_release_name)) == NULL);
 | |
|   FAIL((GET_MIT_FUNCTION(Gssapi32, gss_release_cred)) == NULL);
 | |
|   FAIL((GET_MIT_FUNCTION(Gssapi32, gss_init_sec_context)) == NULL);
 | |
|   FAIL((GET_MIT_FUNCTION(Gssapi32, gss_import_name)) == NULL);
 | |
|   FAIL((GET_MIT_FUNCTION(Gssapi32, gss_get_mic)) == NULL);
 | |
| 
 | |
|   /*
 | |
|    * This is global variable exported by gssapi32.dll.
 | |
|    * Note, that we reveive POINTER not VALUE, so we need to
 | |
|    * do memcpy in this case.
 | |
|    */
 | |
|    
 | |
|   serviceNamePtr = GetProcAddress(Gssapi32, "gss_nt_service_name");
 | |
|   
 | |
|   FAIL(serviceNamePtr == NULL);
 | |
|   
 | |
|   memcpy(&gss_nt_service_name, serviceNamePtr, sizeof(gss_OID));
 | |
|   
 | |
|   /*
 | |
|    * Load functions from krb5_32.dll.
 | |
|    */
 | |
|   
 | |
|   debug("Loading krb5_32.dll...");
 | |
|   
 | |
|   FAIL((Krb5_32 = (HMODULE) LoadLibrary("krb5_32.dll")) == NULL);
 | |
|   
 | |
|   FAIL((GET_MIT_FUNCTION(Krb5_32, krb5_free_context)) == NULL);
 | |
|   FAIL((GET_MIT_FUNCTION(Krb5_32, krb5_free_principal)) == NULL);
 | |
|   FAIL((GET_MIT_FUNCTION(Krb5_32, krb5_cc_destroy)) == NULL);
 | |
| 
 | |
|   /*
 | |
|    * Error handler.
 | |
|    */
 | |
|    
 | |
|   exitCode = 0;
 | |
| 
 | |
|   fail:
 | |
|   
 | |
|   if (exitCode)
 | |
|   {
 | |
|     UninitMitKerberos();
 | |
|     
 | |
|     error("Cannot load MIT KfW libraries. Error code is: %u.\n"
 | |
|               "Please ensure that path to these libraries is properly "
 | |
|                   "set in your PATH variable.\n", GetLastError());
 | |
|   }
 | |
|   
 | |
|   return exitCode;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Free MIT KfW libraries if loaded before.
 | |
|  */
 | |
|  
 | |
| void UninitMitKerberos()
 | |
| {
 | |
|   FreeLibrary(Krb5_32);
 | |
|   FreeLibrary(Comerr32);
 | |
|   FreeLibrary(Gssapi32);
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Fake GSSAPI functions. We pass control to runtime loaded
 | |
|  * KfW libs here.
 | |
|  */
 | |
| 
 | |
| #ifdef __MINGW32__
 | |
| KFW_CALL gss_indicate_mechs(OM_uint32 *a, gss_OID_set *b)
 | |
| #else
 | |
| OM_uint32 KRB5_CALLCONV  gss_indicate_mechs(OM_uint32 *a, gss_OID_set *b)
 | |
| #endif
 | |
| {
 | |
|   return MitDispatch.gss_indicate_mechs(a, b);
 | |
| }
 | |
| #ifdef __MINGW32__
 | |
| KFW_CALL gss_release_buffer(OM_uint32 *a, gss_buffer_t b)
 | |
| #else
 | |
| OM_uint32 KRB5_CALLCONV  gss_release_buffer(OM_uint32 *a, gss_buffer_t b)
 | |
| #endif
 | |
| {
 | |
|   return MitDispatch.gss_release_buffer(a, b);
 | |
| }
 | |
| #ifdef __MINGW32__
 | |
| KFW_CALL gss_display_status(OM_uint32 *a, OM_uint32 b, int c, gss_OID d, 
 | |
|                                 OM_uint32 *e, gss_buffer_t f)
 | |
| #else
 | |
| OM_uint32 KRB5_CALLCONV  gss_display_status(OM_uint32 *a, OM_uint32 b, int c, gss_OID d,
 | |
| 	OM_uint32 *e, gss_buffer_t f)
 | |
| #endif
 | |
| {
 | |
|   return MitDispatch.gss_display_status(a, b, c, d, e, f);
 | |
| }
 | |
| #ifdef __MINGW32__
 | |
| KFW_CALL gss_delete_sec_context(OM_uint32 *a, gss_ctx_id_t *b, gss_buffer_t c)
 | |
| #else
 | |
| OM_uint32 KRB5_CALLCONV  gss_delete_sec_context(OM_uint32 *a, gss_ctx_id_t *b, gss_buffer_t c)
 | |
| #endif
 | |
| {
 | |
|   return MitDispatch.gss_delete_sec_context(a, b, c);
 | |
| }
 | |
| #ifdef __MINGW32__
 | |
| KFW_CALL gss_release_name(OM_uint32 *a, gss_name_t *b)
 | |
| #else
 | |
| OM_uint32 KRB5_CALLCONV  gss_release_name(OM_uint32 *a, gss_name_t *b)
 | |
| #endif
 | |
| {
 | |
|   return MitDispatch.gss_release_name(a, b);
 | |
| }
 | |
| #ifdef __MINGW32__
 | |
| KFW_CALL gss_release_cred(OM_uint32 *a, gss_cred_id_t *b)
 | |
| #else
 | |
| OM_uint32 KRB5_CALLCONV  gss_release_cred(OM_uint32 *a, gss_cred_id_t *b)
 | |
| #endif
 | |
| {
 | |
|   return MitDispatch.gss_release_cred(a, b);
 | |
| }
 | |
| #ifdef __MINGW32__
 | |
| KFW_CALL gss_init_sec_context(OM_uint32 *a, gss_cred_id_t b,
 | |
|                                   gss_ctx_id_t *c, gss_name_t d,
 | |
|                                       gss_OID e, OM_uint32 f,
 | |
|                                           OM_uint32 g, gss_channel_bindings_t h,
 | |
|                                               gss_buffer_t i, gss_OID * j,
 | |
|                                                   gss_buffer_t k, OM_uint32 *l,
 | |
|                                                       OM_uint32 *m)
 | |
| #else
 | |
| OM_uint32 KRB5_CALLCONV  gss_init_sec_context(OM_uint32 *a, gss_cred_id_t b,
 | |
| 	gss_ctx_id_t *c, gss_name_t d,
 | |
| 	gss_OID e, OM_uint32 f,
 | |
| 	OM_uint32 g, gss_channel_bindings_t h,
 | |
| 	gss_buffer_t i, gss_OID * j,
 | |
| 	gss_buffer_t k, OM_uint32 *l,
 | |
| 	OM_uint32 *m)
 | |
| #endif
 | |
| {
 | |
|   return MitDispatch.gss_init_sec_context(a, b, c, d, e, f, g, h, i, j, k, l, m);
 | |
| }
 | |
| #ifdef __MINGW32__
 | |
| KFW_CALL gss_import_name(OM_uint32 *a, gss_buffer_t b, gss_OID c, gss_name_t *d)
 | |
| #else
 | |
| OM_uint32 KRB5_CALLCONV  gss_import_name(OM_uint32 *a, gss_buffer_t b, gss_OID c, gss_name_t *d)
 | |
| #endif
 | |
| {
 | |
|   return MitDispatch.gss_import_name(a, b, c, d);
 | |
| }
 | |
| #ifdef __MINGW32__
 | |
| KFW_CALL gss_get_mic(OM_uint32 *a, gss_ctx_id_t b, gss_qop_t c,
 | |
|                          gss_buffer_t d, gss_buffer_t e)
 | |
| #else
 | |
| OM_uint32 KRB5_CALLCONV  gss_get_mic(OM_uint32 *a, gss_ctx_id_t b, gss_qop_t c,
 | |
| 	gss_buffer_t d, gss_buffer_t e)
 | |
| #endif
 | |
| {
 | |
|   return MitDispatch.gss_get_mic(a, b, c, d, e);
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Fake KRB5 functions. We pass control to runtime loaded
 | |
|  * KfW libs here.
 | |
|  */
 | |
| 
 | |
| void KRB5_CALLCONV krb5_free_context(krb5_context a)
 | |
| {
 | |
|   MitDispatch.krb5_free_context(a);
 | |
| }
 | |
| 
 | |
| void KRB5_CALLCONV krb5_free_principal(krb5_context a, krb5_principal b)
 | |
| {
 | |
|   MitDispatch.krb5_free_principal(a, b);
 | |
| }
 | |
| 
 | |
| krb5_error_code KRB5_CALLCONV krb5_cc_destroy(krb5_context a, krb5_ccache b)
 | |
| {
 | |
|   return MitDispatch.krb5_cc_destroy(a, b);
 | |
| }
 |