aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.Windows15
-rw-r--r--config.h.win32-openssl4
-rwxr-xr-xinclude/wspiapi.h999
-rwxr-xr-xlib.bat15
-rw-r--r--libssh/connect.c10
-rw-r--r--libssh/dh.c2
-rw-r--r--libssh/server.c2
7 files changed, 1039 insertions, 8 deletions
diff --git a/Makefile.Windows b/Makefile.Windows
index 18335e7b..339038d9 100644
--- a/Makefile.Windows
+++ b/Makefile.Windows
@@ -1,7 +1,11 @@
CC= gcc
-INCS= -I. -Iinclude -Ic:/progra~1/gnuwin32/include
+DLLWRAP=dllwrap.exe
+DEFFILE=libssh.def
+STATICLIB=libssh.a
+LIB="c:\Program files\Microsoft Visual Studio .NET 2003\vc7\bin\lib.exe"
+INCS= -I. -Iinclude -Ic:/openssl/include -I"c:\Program files\gnuwin32\include"
CFLAGS= $(INCS)
-LINK= -L. -Lc:/progra~1/gnuwin32/lib -lws2_32 -lcrypto -lgdi32 -lshell32 -lz
+LINK= -L. c:/openssl/lib/MinGW/libeay32.a "c:\program files\gnuwin32\lib\libz.a" c:\Dev-cpp\lib\libws2_32.a #-lws2_32 ##-lgdi32 -lshell32
libssh_HEADERS= config.h include/libssh/crypto.h include/libssh/libssh.h include/libssh/priv.h include/libssh/server.h include/libssh/sftp.h include/libssh/ssh1.h include/libssh/ssh2.h
libssh_OBJS = libssh/auth1.o libssh/auth.o libssh/base64.o libssh/buffer.o \
@@ -13,7 +17,7 @@ libssh_OBJS = libssh/auth1.o libssh/auth.o libssh/base64.o libssh/buffer.o \
libssh/sftpserver.o libssh/string.o libssh/wrapper.o libssh/socket.o
-all: libssh.dll samplesshd.exe
+all: libssh.dll samplesshd.exe libssh.lib
config.h: config.h.win32-openssl
copy config.h.win32-openssl config.h
@@ -27,7 +31,10 @@ samplesshd.exe: samplesshd.o $(libssh_OBJS)
$(CC) $< -o $@ $(libssh_OBJS) $(LINK)
libssh.dll: $(libssh_OBJS)
- $(CC) -shared $(libssh_OBJS) -o libssh.dll $(LINK)
+# $(CC) -shared $(libssh_OBJS) -o libssh.dll $(LINK)
+ $(DLLWRAP) --export-all-symbols --output-def $(DEFFILE) --implib $(STATICLIB) $(libssh_OBJS) $(LINK) -o libssh.dll
+libssh.lib: libssh.dll
+ lib.bat
clean:
rm -f $(libssh_OBJS) samplesshd.exe sample.exe samplesshd.o sample.o libssh.dll config.h
diff --git a/config.h.win32-openssl b/config.h.win32-openssl
index ac022648..4dc1da9f 100644
--- a/config.h.win32-openssl
+++ b/config.h.win32-openssl
@@ -156,7 +156,7 @@
#define PACKAGE_TARNAME "libssh"
/* Define to the version of this package. */
-#define PACKAGE_VERSION "0.2"
+#define PACKAGE_VERSION "0.2.1-win-svn"
/* Define as the return type of signal handlers (`int' or `void'). */
#define RETSIGTYPE void
@@ -177,7 +177,7 @@
#define TIME_WITH_SYS_TIME 1
/* Version number of package */
-#define VERSION "0.2"
+#define VERSION "0.2.1-win-svn"
/* Define to 1 if your processor stores words with the most significant byte
first (like Motorola and SPARC, unlike Intel and VAX). */
diff --git a/include/wspiapi.h b/include/wspiapi.h
new file mode 100755
index 00000000..eaa4ec2f
--- /dev/null
+++ b/include/wspiapi.h
@@ -0,0 +1,999 @@
+/*++
+
+Copyright (c) 2000, Microsoft Corporation
+
+Module Name:
+ wspiapi.h
+
+Abstract:
+ The file contains protocol independent API functions.
+
+Revision History:
+ Wed Jul 12 10:50:31 2000, Created
+
+--*/
+
+#ifndef _WSPIAPI_H_
+#define _WSPIAPI_H_
+
+#include <stdio.h> // sprintf()
+#include <stdlib.h> // calloc(), strtoul()
+#include <malloc.h> // calloc()
+#include <string.h> // strlen(), strcmp(), strstr()
+
+#define WspiapiMalloc(tSize) calloc(1, (tSize))
+#define WspiapiFree(p) free(p)
+#define WspiapiSwap(a, b, c) { (c) = (a); (a) = (b); (b) = (c); }
+#define getaddrinfo WspiapiGetAddrInfo
+#define getnameinfo WspiapiGetNameInfo
+#define freeaddrinfo WspiapiFreeAddrInfo
+
+typedef int (WINAPI *WSPIAPI_PGETADDRINFO) (
+ IN const char *nodename,
+ IN const char *servname,
+ IN const struct addrinfo *hints,
+ OUT struct addrinfo **res);
+
+typedef int (WINAPI *WSPIAPI_PGETNAMEINFO) (
+ IN const struct sockaddr *sa,
+ IN socklen_t salen,
+ OUT char *host,
+ IN size_t hostlen,
+ OUT char *serv,
+ IN size_t servlen,
+ IN int flags);
+
+typedef void (WINAPI *WSPIAPI_PFREEADDRINFO) (
+ IN struct addrinfo *ai);
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+////////////////////////////////////////////////////////////
+// v4 only versions of getaddrinfo and friends.
+// NOTE: gai_strerror is inlined in ws2tcpip.h
+////////////////////////////////////////////////////////////
+
+__inline
+char *
+WINAPI
+WspiapiStrdup (
+ IN const char * pszString)
+/*++
+
+Routine Description
+ allocates enough storage via calloc() for a copy of the string,
+ copies the string into the new memory, and returns a pointer to it.
+
+Arguments
+ pszString string to copy into new memory
+
+Return Value
+ a pointer to the newly allocated storage with the string in it.
+ NULL if enough memory could not be allocated, or string was NULL.
+
+--*/
+{
+ char *pszMemory;
+
+ if (!pszString)
+ return(NULL);
+
+ pszMemory = (char *) WspiapiMalloc(strlen(pszString) + 1);
+ if (!pszMemory)
+ return(NULL);
+
+ return(strcpy(pszMemory, pszString));
+}
+
+
+
+__inline
+BOOL
+WINAPI
+WspiapiParseV4Address (
+ IN const char * pszAddress,
+ OUT PDWORD pdwAddress)
+/*++
+
+Routine Description
+ get the IPv4 address (in network byte order) from its string
+ representation. the syntax should be a.b.c.d.
+
+Arguments
+ pszArgument string representation of the IPv4 address
+ ptAddress pointer to the resulting IPv4 address
+
+Return Value
+ Returns FALSE if there is an error, TRUE for success.
+
+--*/
+{
+ DWORD dwAddress = 0;
+ const char *pcNext = NULL;
+ int iCount = 0;
+
+ // ensure there are 3 '.' (periods)
+ for (pcNext = pszAddress; *pcNext != '\0'; pcNext++)
+ if (*pcNext == '.')
+ iCount++;
+ if (iCount != 3)
+ return FALSE;
+
+ // return an error if dwAddress is INADDR_NONE (255.255.255.255)
+ // since this is never a valid argument to getaddrinfo.
+ dwAddress = inet_addr(pszAddress);
+ if (dwAddress == INADDR_NONE)
+ return FALSE;
+
+ *pdwAddress = dwAddress;
+ return TRUE;
+}
+
+
+
+__inline
+struct addrinfo *
+WINAPI
+WspiapiNewAddrInfo (
+ IN int iSocketType,
+ IN int iProtocol,
+ IN WORD wPort,
+ IN DWORD dwAddress)
+/*++
+
+Routine Description
+ allocate an addrinfo structure and populate fields.
+ IPv4 specific internal function, not exported.
+
+Arguments
+ iSocketType SOCK_*. can be wildcarded (zero).
+ iProtocol IPPROTO_*. can be wildcarded (zero).
+ wPort port number of service (in network order).
+ dwAddress IPv4 address (in network order).
+
+Return Value
+ returns an addrinfo struct, or NULL if out of memory.
+
+--*/
+{
+ struct addrinfo *ptNew;
+ struct sockaddr_in *ptAddress;
+
+ // allocate a new addrinfo structure.
+ ptNew =
+ (struct addrinfo *) WspiapiMalloc(sizeof(struct addrinfo));
+ if (!ptNew)
+ return NULL;
+
+ ptAddress =
+ (struct sockaddr_in *) WspiapiMalloc(sizeof(struct sockaddr_in));
+ if (!ptAddress)
+ {
+ WspiapiFree(ptNew);
+ return NULL;
+ }
+ ptAddress->sin_family = AF_INET;
+ ptAddress->sin_port = wPort;
+ ptAddress->sin_addr.s_addr = dwAddress;
+
+ // fill in the fields...
+ ptNew->ai_family = PF_INET;
+ ptNew->ai_socktype = iSocketType;
+ ptNew->ai_protocol = iProtocol;
+ ptNew->ai_addrlen = sizeof(struct sockaddr_in);
+ ptNew->ai_addr = (struct sockaddr *) ptAddress;
+
+ return ptNew;
+}
+
+
+
+__inline
+int
+WINAPI
+WspiapiQueryDNS(
+ IN const char *pszNodeName,
+ IN int iSocketType,
+ IN int iProtocol,
+ IN WORD wPort,
+ OUT char *pszAlias,
+ OUT struct addrinfo **pptResult)
+/*++
+
+Routine Description
+ helper routine for WspiapiLookupNode.
+ performs name resolution by querying the DNS for A records.
+ *pptResult would need to be freed if an error is returned.
+
+Arguments
+ pszNodeName name of node to resolve.
+ iSocketType SOCK_*. can be wildcarded (zero).
+ iProtocol IPPROTO_*. can be wildcarded (zero).
+ wPort port number of service (in network order).
+ pszAlias where to return the alias.
+ pptResult where to return the result.
+
+Return Value
+ Returns 0 on success, an EAI_* style error value otherwise.
+
+--*/
+{
+ struct addrinfo **pptNext = pptResult;
+ struct hostent *ptHost = NULL;
+ char **ppAddresses;
+
+ *pptNext = NULL;
+ pszAlias[0] = '\0';
+
+ ptHost = gethostbyname(pszNodeName);
+ if (ptHost)
+ {
+ if ((ptHost->h_addrtype == AF_INET) &&
+ (ptHost->h_length == sizeof(struct in_addr)))
+ {
+ for (ppAddresses = ptHost->h_addr_list;
+ *ppAddresses != NULL;
+ ppAddresses++)
+ {
+ // create an addrinfo structure...
+ *pptNext = WspiapiNewAddrInfo(
+ iSocketType,
+ iProtocol,
+ wPort,
+ ((struct in_addr *) *ppAddresses)->s_addr);
+ if (!*pptNext)
+ return EAI_MEMORY;
+
+ pptNext = &((*pptNext)->ai_next);
+ }
+ }
+
+ // pick up the canonical name.
+ strcpy(pszAlias, ptHost->h_name);
+ return 0;
+ }
+
+ switch (WSAGetLastError())
+ {
+ case WSAHOST_NOT_FOUND: return EAI_NONAME;
+ case WSATRY_AGAIN: return EAI_AGAIN;
+ case WSANO_RECOVERY: return EAI_FAIL;
+ case WSANO_DATA: return EAI_NODATA;
+ default: return EAI_NONAME;
+ }
+}
+
+
+
+__inline
+int
+WINAPI
+WspiapiLookupNode(
+ IN const char *pszNodeName,
+ IN int iSocketType,
+ IN int iProtocol,
+ IN WORD wPort,
+ IN BOOL bAI_CANONNAME,
+ OUT struct addrinfo **pptResult)
+/*++
+
+Routine Description
+ resolve a nodename and return a list of addrinfo structures.
+ IPv4 specific internal function, not exported.
+ *pptResult would need to be freed if an error is returned.
+
+ NOTE: if bAI_CANONNAME is true, the canonical name should be
+ returned in the first addrinfo structure.
+
+Arguments
+ pszNodeName name of node to resolve.
+ iSocketType SOCK_*. can be wildcarded (zero).
+ iProtocol IPPROTO_*. can be wildcarded (zero).
+ wPort port number of service (in network order).
+ bAI_CANONNAME whether the AI_CANONNAME flag is set.
+ pptResult where to return result.
+
+Return Value
+ Returns 0 on success, an EAI_* style error value otherwise.
+
+--*/
+{
+ int iError = 0;
+ int iAliasCount = 0;
+
+ char szFQDN1[NI_MAXHOST] = "";
+ char szFQDN2[NI_MAXHOST] = "";
+ char *pszName = szFQDN1;
+ char *pszAlias = szFQDN2;
+ char *pszScratch = NULL;
+ strcpy(pszName, pszNodeName);
+
+ for (;;)
+ {
+ iError = WspiapiQueryDNS(pszNodeName,
+ iSocketType,
+ iProtocol,
+ wPort,
+ pszAlias,
+ pptResult);
+ if (iError)
+ break;
+
+ // if we found addresses, then we are done.
+ if (*pptResult)
+ break;
+
+ // stop infinite loops due to DNS misconfiguration. there appears
+ // to be no particular recommended limit in RFCs 1034 and 1035.
+ if ((!strlen(pszAlias)) ||
+ (!strcmp(pszName, pszAlias)) ||
+ (++iAliasCount == 16))
+ {
+ iError = EAI_FAIL;
+ break;
+ }
+
+ // there was a new CNAME, look again.
+ WspiapiSwap(pszName, pszAlias, pszScratch);
+ }
+
+ if (!iError && bAI_CANONNAME)
+ {
+ (*pptResult)->ai_canonname = WspiapiStrdup(pszAlias);
+ if (!(*pptResult)->ai_canonname)
+ iError = EAI_MEMORY;
+ }
+
+ return iError;
+}
+
+
+
+__inline
+int
+WINAPI
+WspiapiClone (
+ IN WORD wPort,
+ IN struct addrinfo *ptResult)
+/*++
+
+Routine Description
+ clone every addrinfo structure in ptResult for the UDP service.
+ ptResult would need to be freed if an error is returned.
+
+Arguments
+ wPort port number of UDP service.
+ ptResult list of addrinfo structures, each
+ of whose node needs to be cloned.
+
+Return Value
+ Returns 0 on success, an EAI_MEMORY on allocation failure.
+
+--*/
+{
+ struct addrinfo *ptNext = NULL;
+ struct addrinfo *ptNew = NULL;
+
+ for (ptNext = ptResult; ptNext != NULL; )
+ {
+ // create an addrinfo structure...
+ ptNew = WspiapiNewAddrInfo(
+ SOCK_DGRAM,
+ ptNext->ai_protocol,
+ wPort,
+ ((struct sockaddr_in *) ptNext->ai_addr)->sin_addr.s_addr);
+ if (!ptNew)
+ break;
+
+ // link the cloned addrinfo
+ ptNew->ai_next = ptNext->ai_next;
+ ptNext->ai_next = ptNew;
+ ptNext = ptNew->ai_next;
+ }
+
+ if (ptNext != NULL)
+ return EAI_MEMORY;
+
+ return 0;
+}
+
+
+
+__inline
+void
+WINAPI
+WspiapiLegacyFreeAddrInfo (
+ IN struct addrinfo *ptHead)
+/*++
+
+Routine Description
+ Free an addrinfo structure (or chain of structures).
+ As specified in RFC 2553, Section 6.4.
+
+Arguments
+ ptHead structure (chain) to free
+
+--*/
+{
+ struct addrinfo *ptNext; // next strcture to free
+
+ for (ptNext = ptHead; ptNext != NULL; ptNext = ptHead)
+ {
+ if (ptNext->ai_canonname)
+ WspiapiFree(ptNext->ai_canonname);
+
+ if (ptNext->ai_addr)
+ WspiapiFree(ptNext->ai_addr);
+
+ ptHead = ptNext->ai_next;
+ WspiapiFree(ptNext);
+ }
+}
+
+
+
+__inline
+int
+WINAPI
+WspiapiLegacyGetAddrInfo(
+ IN const char *pszNodeName,
+ IN const char *pszServiceName,
+ IN const struct addrinfo *ptHints,
+ OUT struct addrinfo **pptResult)
+/*++
+
+Routine Description
+ Protocol-independent name-to-address translation.
+ As specified in RFC 2553, Section 6.4.
+ This is the hacked version that only supports IPv4.
+
+Arguments
+ pszNodeName node name to lookup.
+ pszServiceName service name to lookup.
+ ptHints hints about how to process request.
+ pptResult where to return result.
+
+Return Value
+ returns zero if successful, an EAI_* error code if not.
+
+--*/
+{
+ int iError = 0;
+ int iFlags = 0;
+ int iFamily = PF_UNSPEC;
+ int iSocketType = 0;
+ int iProtocol = 0;
+ WORD wPort = 0;
+ DWORD dwAddress = 0;
+
+ struct servent *ptService = NULL;
+ char *pc = NULL;
+ BOOL bClone = FALSE;
+ WORD wTcpPort = 0;
+ WORD wUdpPort = 0;
+
+
+ // initialize pptResult with default return value.
+ *pptResult = NULL;
+
+
+ ////////////////////////////////////////
+ // validate arguments...
+ //
+
+ // both the node name and the service name can't be NULL.
+ if ((!pszNodeName) && (!pszServiceName))
+ return EAI_NONAME;
+
+ // validate hints.
+ if (ptHints)
+ {
+ // all members other than ai_flags, ai_family, ai_socktype
+ // and ai_protocol must be zero or a null pointer.
+ if ((ptHints->ai_addrlen != 0) ||
+ (ptHints->ai_canonname != NULL) ||
+ (ptHints->ai_addr != NULL) ||
+ (ptHints->ai_next != NULL))
+ {
+ return EAI_FAIL;
+ }
+
+ // the spec has the "bad flags" error code, so presumably we
+ // should check something here. insisting that there aren't
+ // any unspecified flags set would break forward compatibility,
+ // however. so we just check for non-sensical combinations.
+ //
+ // we cannot come up with a canonical name given a null node name.
+ iFlags = ptHints->ai_flags;
+ if ((iFlags & AI_CANONNAME) && !pszNodeName)
+ return EAI_BADFLAGS;
+
+ // we only support a limited number of protocol families.
+ iFamily = ptHints->ai_family;
+ if ((iFamily != PF_UNSPEC) && (iFamily != PF_INET))
+ return EAI_FAMILY;
+
+ // we only support only these socket types.
+ iSocketType = ptHints->ai_socktype;
+ if ((iSocketType != 0) &&
+ (iSocketType != SOCK_STREAM) &&
+ (iSocketType != SOCK_DGRAM) &&
+ (iSocketType != SOCK_RAW))
+ return EAI_SOCKTYPE;
+
+ // REVIEW: What if ai_socktype and ai_protocol are at odds?
+ iProtocol = ptHints->ai_protocol;
+ }
+
+
+ ////////////////////////////////////////
+ // do service lookup...
+
+ if (pszServiceName)
+ {
+ wPort = (WORD) strtoul(pszServiceName, &pc, 10);
+ if (*pc == '\0') // numeric port string
+ {
+ wPort = wTcpPort = wUdpPort = htons(wPort);
+ if (iSocketType == 0)
+ {
+ bClone = TRUE;
+ iSocketType = SOCK_STREAM;
+ }
+ }
+ else // non numeric port string
+ {
+ if ((iSocketType == 0) || (iSocketType == SOCK_DGRAM))
+ {
+ ptService = getservbyname(pszServiceName, "udp");
+ if (ptService)
+ wPort = wUdpPort = ptService->s_port;
+ }
+
+ if ((iSocketType == 0) || (iSocketType == SOCK_STREAM))
+ {
+ ptService = getservbyname(pszServiceName, "tcp");
+ if (ptService)
+ wPort = wTcpPort = ptService->s_port;
+ }
+
+ // assumes 0 is an invalid service port...
+ if (wPort == 0) // no service exists
+ return (iSocketType ? EAI_SERVICE : EAI_NONAME);
+
+ if (iSocketType == 0)
+ {
+ // if both tcp and udp, process tcp now & clone udp later.
+ iSocketType = (wTcpPort) ? SOCK_STREAM : SOCK_DGRAM;
+ bClone = (wTcpPort && wUdpPort);
+ }
+ }
+ }
+
+
+
+ ////////////////////////////////////////
+ // do node name lookup...
+
+ // if we weren't given a node name,
+ // return the wildcard or loopback address (depending on AI_PASSIVE).
+ //
+ // if we have a numeric host address string,
+ // return the binary address.
+ //
+ if ((!pszNodeName) || (WspiapiParseV4Address(pszNodeName, &dwAddress)))
+ {
+ if (!pszNodeName)
+ {
+ dwAddress = htonl((iFlags & AI_PASSIVE)
+ ? INADDR_ANY
+ : INADDR_LOOPBACK);
+ }
+
+ // create an addrinfo structure...
+ *pptResult =
+ WspiapiNewAddrInfo(iSocketType, iProtocol, wPort, dwAddress);
+ if (!(*pptResult))
+ iError = EAI_MEMORY;
+
+ if (!iError && pszNodeName)
+ {
+ // implementation specific behavior: set AI_NUMERICHOST
+ // to indicate that we got a numeric host address string.
+ (*pptResult)->ai_flags |= AI_NUMERICHOST;
+
+ // return the numeric address string as the canonical name
+ if (iFlags & AI_CANONNAME)
+ {
+ (*pptResult)->ai_canonname =
+ WspiapiStrdup(inet_ntoa(*((struct in_addr *) &dwAddress)));
+ if (!(*pptResult)->ai_canonname)
+ iError = EAI_MEMORY;
+ }
+ }
+ }
+
+
+ // if we do not have a numeric host address string and
+ // AI_NUMERICHOST flag is set, return an error!
+ else if (iFlags & AI_NUMERICHOST)
+ {
+ iError = EAI_NONAME;
+ }
+
+
+ // since we have a non-numeric node name,
+ // we have to do a regular node name lookup.
+ else
+ {
+ iError = WspiapiLookupNode(pszNodeName,
+ iSocketType,
+ iProtocol,
+ wPort,
+ (iFlags & AI_CANONNAME),
+ pptResult);
+ }
+
+ if (!iError && bClone)
+ {
+ iError = WspiapiClone(wUdpPort, *pptResult);
+ }
+
+ if (iError)
+ {
+ WspiapiLegacyFreeAddrInfo(*pptResult);
+ *pptResult = NULL;
+ }
+
+ return (iError);
+}
+
+
+
+__inline
+int
+WINAPI
+WspiapiLegacyGetNameInfo(
+ IN const struct sockaddr *ptSocketAddress,
+ IN socklen_t tSocketLength,
+ OUT char *pszNodeName,
+ IN size_t tNodeLength,
+ OUT char *pszServiceName,
+ IN size_t tServiceLength,
+ IN int iFlags)
+/*++
+
+Routine Description
+ protocol-independent address-to-name translation.
+ as specified in RFC 2553, Section 6.5.
+ this is the hacked version that only supports IPv4.
+
+Arguments
+ ptSocketAddress socket address to translate.
+ tSocketLength length of above socket address.
+ pszNodeName where to return the node name.
+ tNodeLength size of above buffer.
+ pszServiceName where to return the service name.
+ tServiceLength size of above buffer.
+ iFlags flags of type NI_*.
+
+Return Value
+ returns zero if successful, an EAI_* error code if not.
+
+--*/
+{
+ struct servent *ptService;
+ WORD wPort;
+ char szBuffer[] = "65535";
+ char *pszService = szBuffer;
+
+ struct hostent *ptHost;
+ struct in_addr tAddress;
+ char *pszNode = NULL;
+ char *pc = NULL;
+
+
+ // sanity check ptSocketAddress and tSocketLength.
+ if (!ptSocketAddress)
+ return EAI_FAIL;
+
+ if ((ptSocketAddress->sa_family != AF_INET) ||
+ (tSocketLength != sizeof(struct sockaddr_in)))
+ {
+ return EAI_FAMILY;
+ }
+
+ if (!(pszNodeName && tNodeLength) &&
+ !(pszServiceName && tServiceLength))
+ {
+ return EAI_NONAME;
+ }
+
+ // the draft has the "bad flags" error code, so presumably we
+ // should check something here. insisting that there aren't
+ // any unspecified flags set would break forward compatibility,
+ // however. so we just check for non-sensical combinations.
+ if ((iFlags & NI_NUMERICHOST) && (iFlags & NI_NAMEREQD))
+ {
+ return EAI_BADFLAGS;
+ }
+
+ // translate the port to a service name (if requested).
+ if (pszServiceName && tServiceLength)
+ {
+ wPort = ((struct sockaddr_in *) ptSocketAddress)->sin_port;
+
+ if (iFlags & NI_NUMERICSERV)
+ {
+ // return numeric form of the address.
+ sprintf(szBuffer, "%u", ntohs(wPort));
+ }
+ else
+ {
+ // return service name corresponding to port.
+ ptService = getservbyport(wPort,
+ (iFlags & NI_DGRAM) ? "udp" : NULL);
+ if (ptService && ptService->s_name)
+ {
+ // lookup successful.
+ pszService = ptService->s_name;
+ }
+ else
+ {
+ // DRAFT: return numeric form of the port!
+ sprintf(szBuffer, "%u", ntohs(wPort));
+ }
+ }
+
+
+ if (tServiceLength > strlen(pszService))
+ strcpy(pszServiceName, pszService);
+ else
+ return EAI_FAIL;
+ }
+
+
+ // translate the address to a node name (if requested).
+ if (pszNodeName && tNodeLength)
+ {
+ // this is the IPv4-only version, so we have an IPv4 address.
+ tAddress = ((struct sockaddr_in *) ptSocketAddress)->sin_addr;
+
+ if (iFlags & NI_NUMERICHOST)
+ {
+ // return numeric form of the address.
+ pszNode = inet_ntoa(tAddress);
+ }
+ else
+ {
+ // return node name corresponding to address.
+ ptHost = gethostbyaddr((char *) &tAddress,
+ sizeof(struct in_addr),
+ AF_INET);
+ if (ptHost && ptHost->h_name)
+ {
+ // DNS lookup successful.
+ // stop copying at a "." if NI_NOFQDN is specified.
+ pszNode = ptHost->h_name;
+ if ((iFlags & NI_NOFQDN) && (pc = strchr(pszNode, '.')))
+ *pc = '\0';
+ }
+ else
+ {
+ // DNS lookup failed. return numeric form of the address.
+ if (iFlags & NI_NAMEREQD)
+ {
+ switch (WSAGetLastError())
+ {
+ case WSAHOST_NOT_FOUND: return EAI_NONAME;
+ case WSATRY_AGAIN: return EAI_AGAIN;
+ case WSANO_RECOVERY: return EAI_FAIL;
+ default: return EAI_NONAME;
+ }
+ }
+ else
+ pszNode = inet_ntoa(tAddress);
+ }
+ }
+
+ if (tNodeLength > strlen(pszNode))
+ strcpy(pszNodeName, pszNode);
+ else
+ return EAI_FAIL;
+ }
+
+ return 0;
+}
+
+
+
+typedef struct
+{
+ char const *pszName;
+ FARPROC pfAddress;
+} WSPIAPI_FUNCTION;
+
+#define WSPIAPI_FUNCTION_ARRAY \
+{ \
+ "getaddrinfo", (FARPROC) WspiapiLegacyGetAddrInfo, \
+ "getnameinfo", (FARPROC) WspiapiLegacyGetNameInfo, \
+ "freeaddrinfo", (FARPROC) WspiapiLegacyFreeAddrInfo, \
+}
+
+
+
+__inline
+FARPROC
+WINAPI
+WspiapiLoad(
+ IN WORD wFunction)
+/*++
+
+Routine Description
+ try to locate the address family independent name resolution routines
+ (i.e. getaddrinfo, getnameinfo, freeaddrinfo, gai_strerror).
+
+Locks
+ this function call is not synchronized. hence the library containing
+ the routines might be loaded multiple times. another option is to
+ synchronize through a spin lock using a static local variable and the
+ InterlockedExchange operation.
+
+
+Arguments
+ wFunction ordinal # of the function to get the pointer to
+ 0 getaddrinfo
+ 1 getnameinfo
+ 2 freeaddrinfo
+
+Return Value
+ address of the library/legacy routine
+
+--*/
+{
+ HMODULE hLibrary = NULL;
+
+ // these static variables store state across calls, across threads.
+ static BOOL bInitialized = FALSE;
+ static WSPIAPI_FUNCTION rgtGlobal[] = WSPIAPI_FUNCTION_ARRAY;
+ static const int iNumGlobal = (sizeof(rgtGlobal) /
+ sizeof(WSPIAPI_FUNCTION));
+
+ // we overwrite rgtGlobal only if all routines exist in library.
+ WSPIAPI_FUNCTION rgtLocal[] = WSPIAPI_FUNCTION_ARRAY;
+ FARPROC fScratch = NULL;
+ int i = 0;
+
+
+ if (bInitialized) // WspiapiLoad has already been called once
+ return (rgtGlobal[wFunction].pfAddress);
+
+ do // breakout loop
+ {
+ // in Whistler and beyond...
+ // the routines are present in the WinSock 2 library (ws2_32.dll).
+ // printf("Looking in ws2_32 for getaddrinfo...\n");
+ hLibrary = LoadLibraryA("ws2_32");
+ if (hLibrary != NULL)
+ {
+ fScratch = GetProcAddress(hLibrary, "getaddrinfo");
+ if (fScratch == NULL)
+ {
+ FreeLibrary(hLibrary);
+ hLibrary = NULL;
+ }
+ }
+ if (hLibrary != NULL)
+ break;
+
+
+ // in the IPv6 Technology Preview...
+ // the routines are present in the IPv6 WinSock library (wship6.dll).
+ // printf("Looking in wship6 for getaddrinfo...\n");
+ hLibrary = LoadLibraryA("wship6");
+ if (hLibrary != NULL)
+ {
+ fScratch = GetProcAddress(hLibrary, "getaddrinfo");
+ if (fScratch == NULL)
+ {
+ FreeLibrary(hLibrary);
+ hLibrary = NULL;
+ }
+ }
+ } while (FALSE);
+
+
+ if (hLibrary != NULL)
+ {
+ // use routines from this library...
+ // since getaddrinfo is here, we expect all routines to be here,
+ // but will fall back to IPv4-only if any of them is missing.
+ for (i = 0; i < iNumGlobal; i++)
+ {
+ rgtLocal[i].pfAddress
+ = GetProcAddress(hLibrary, rgtLocal[i].pszName);
+ if (rgtLocal[i].pfAddress == NULL)
+ {
+ FreeLibrary(hLibrary);
+ hLibrary = NULL;
+ break;
+ }
+ }
+
+ if (hLibrary != NULL)
+ {
+ // printf("found!\n");
+ for (i = 0; i < iNumGlobal; i++)
+ rgtGlobal[i].pfAddress = rgtLocal[i].pfAddress;
+ }
+ }
+
+ bInitialized = TRUE;
+ return (rgtGlobal[wFunction].pfAddress);
+}
+
+
+
+__inline
+int
+WINAPI
+WspiapiGetAddrInfo(
+ IN const char *nodename,
+ IN const char *servname,
+ IN const struct addrinfo *hints,
+ OUT struct addrinfo **res)
+{
+ static WSPIAPI_PGETADDRINFO pfGetAddrInfo = NULL;
+
+ if (!pfGetAddrInfo)
+ pfGetAddrInfo = (WSPIAPI_PGETADDRINFO) WspiapiLoad(0);
+ return ((*pfGetAddrInfo)
+ (nodename, servname, hints, res));
+}
+
+
+
+__inline
+int
+WINAPI
+WspiapiGetNameInfo (
+ IN const struct sockaddr *sa,
+ IN socklen_t salen,
+ OUT char *host,
+ IN size_t hostlen,
+ OUT char *serv,
+ IN size_t servlen,
+ IN int flags)
+{
+ static WSPIAPI_PGETNAMEINFO pfGetNameInfo = NULL;
+
+ if (!pfGetNameInfo)
+ pfGetNameInfo = (WSPIAPI_PGETNAMEINFO) WspiapiLoad(1);
+ return ((*pfGetNameInfo)
+ (sa, salen, host, hostlen, serv, servlen, flags));
+}
+
+
+
+__inline
+void
+WINAPI
+WspiapiFreeAddrInfo (
+ IN struct addrinfo *ai)
+{
+ static WSPIAPI_PFREEADDRINFO pfFreeAddrInfo = NULL;
+
+ if (!pfFreeAddrInfo)
+ pfFreeAddrInfo = (WSPIAPI_PFREEADDRINFO) WspiapiLoad(2);
+ (*pfFreeAddrInfo)(ai);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _WSPIAPI_H_
diff --git a/lib.bat b/lib.bat
new file mode 100755
index 00000000..2d2807de
--- /dev/null
+++ b/lib.bat
@@ -0,0 +1,15 @@
+@SET VSINSTALLDIR=C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\IDE
+@SET VCINSTALLDIR=C:\Program Files\Microsoft Visual Studio .NET 2003
+@SET FrameworkDir=C:\WINDOWS\Microsoft.NET\Framework
+@SET FrameworkVersion=v1.1.4322
+@SET FrameworkSDKDir=C:\Program Files\Microsoft Visual Studio .NET 2003\SDK\v1.1
+@set DevEnvDir=%VSINSTALLDIR%
+
+@rem
+@rem Root of Visual C++ installed files.
+@rem
+@set MSVCDir=%VCINSTALLDIR%\VC7
+@set PATH=%DevEnvDir%;%MSVCDir%\BIN;%VCINSTALLDIR%\Common7\Tools;%VCINSTALLDIR%\Common7\Tools\bin\prerelease;%VCINSTALLDIR%\Common7\Tools\bin;%FrameworkSDKDir%\bin;%FrameworkDir%\%FrameworkVersion%;%PATH%;
+@set INCLUDE=%MSVCDir%\ATLMFC\INCLUDE;%MSVCDir%\INCLUDE;%MSVCDir%\PlatformSDK\include\prerelease;%MSVCDir%\PlatformSDK\include;%FrameworkSDKDir%\include;%INCLUDE%
+@set LIB=%MSVCDir%\ATLMFC\LIB;%MSVCDir%\LIB;%MSVCDir%\PlatformSDK\lib\prerelease;%MSVCDir%\PlatformSDK\lib;%FrameworkSDKDir%\lib;%LIB%
+"c:\Program files\Microsoft Visual Studio .NET 2003\vc7\bin\lib.exe" /machine:i386 /def:libssh.def
diff --git a/libssh/connect.c b/libssh/connect.c
index 6470b5a9..9f865bbd 100644
--- a/libssh/connect.c
+++ b/libssh/connect.c
@@ -29,6 +29,7 @@ MA 02111-1307, USA. */
#define _WIN32_WINNT 0x0501 //getaddrinfo, freeaddrinfo, getnameinfo
#include <winsock2.h>
#include <ws2tcpip.h>
+#include "wspiapi.h"
#else
#include <netdb.h>
#include <sys/socket.h>
@@ -62,6 +63,13 @@ static void sock_set_blocking(socket_t sock){
u_long nonblocking = 0;
ioctlsocket(sock, FIONBIO, &nonblocking);
}
+
+char WSAAPI *gai_strerrorA(int code){
+ static char buffer[256];
+ snprintf(buffer,256,"Undetermined error code (%d)",code);
+ return buffer;
+}
+
#endif
static int getai(const char *host, int port, struct addrinfo **ai)
@@ -111,7 +119,7 @@ int ssh_connect_ai_timeout(SSH_SESSION *session, const char *host, int port, str
}
ret = 0;
/* get connect(2) return code. zero means no error */
- getsockopt(s,SOL_SOCKET,SO_ERROR,&ret,&len);
+ getsockopt(s,SOL_SOCKET,SO_ERROR,(char *)&ret,&len);
if (ret!=0){
ssh_set_error(session,SSH_FATAL,"Connecting : %s",strerror(ret));
close(s);
diff --git a/libssh/dh.c b/libssh/dh.c
index b8d68248..be660888 100644
--- a/libssh/dh.c
+++ b/libssh/dh.c
@@ -288,6 +288,8 @@ void dh_build_k(SSH_SESSION *session){
}
#endif
#ifdef DEBUG_CRYPTO
+ ssh_print_hexa("session server cookie",session->server_kex.cookie,16);
+ ssh_print_hexa("session client cookie",session->client_kex.cookie,16);
ssh_print_bignum("shared secret key",session->next_crypto->k);
#endif
#ifdef HAVE_LIBCRYPTO
diff --git a/libssh/server.c b/libssh/server.c
index cbc6eea8..ee9f6d4a 100644
--- a/libssh/server.c
+++ b/libssh/server.c
@@ -68,7 +68,7 @@ static socket_t bind_socket(SSH_BIND *ssh_bind,char *hostname, int port) {
memcpy(&myaddr.sin_addr,hp->h_addr,hp->h_length);
myaddr.sin_family=hp->h_addrtype;
myaddr.sin_port = htons(port);
- setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
+ setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt));
if (bind(s, (struct sockaddr *) &myaddr, sizeof(myaddr)) < 0) {
ssh_set_error(ssh_bind,SSH_FATAL,"Binding to %s:%d : %s",hostname,port,
strerror(errno));