]> git.ipfire.org Git - thirdparty/ntp.git/commitdiff
[Bug 2019] Allow selection of cipher for private key files.
authorDave Hart <hart@ntp.org>
Sun, 2 Oct 2011 22:12:47 +0000 (22:12 +0000)
committerDave Hart <hart@ntp.org>
Sun, 2 Oct 2011 22:12:47 +0000 (22:12 +0000)
ntp-keygen private key cipher default now triple-key triple DES CBC.
ntp-keygen on Windows XP and later systems will now create links
  expected by ntpd.  They are hardlinks on Windows, soft on POSIX.

bk: 4e88e1dfUDkggelDOi64F0BK6Vn7xg

ChangeLog
util/ntp-keygen-opts.c
util/ntp-keygen-opts.def
util/ntp-keygen-opts.h
util/ntp-keygen.c

index 0c0c9f7de1006e338d967baf02b3cfd71f38d181..98afa629fd0d38bc0aad3ff780c2b2bf278dbdc8 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,5 @@
+* [Bug 2019] Allow selection of cipher for private key files.
+* ntp-keygen private key cipher default now triple-key triple DES CBC.
 * ntp-keygen -M is intended to ignore all other defaults and
   options, so do not attempt to open existing Autokey host certificate
   before generating symmetric keys and terminating.
@@ -5,6 +7,8 @@
   ntpkey_<scheme>par_<group/host> in ntpd, matching ntp-keygen.
 * Change some error logging to syslog to ignore logconfig mask, such
   as reporting PPSAPI failure in NMEA and WWVB refclocks.
+* ntp-keygen on Windows XP and later systems will now create links
+  expected by ntpd.  They are hardlinks on Windows, soft on POSIX.
 * Conditionalize NMEA serial open message under clockevent.
 * Send all peer variables to trappers in report_event().
 (4.2.7p217) 2011/09/29 Released by Harlan Stenn <stenn@ntp.org>
index b986fa88210d262dc79f8d7d9d00247dbbe7eebc..77a2b115ffbd0335288933bf376ff41b5e990b40 100644 (file)
@@ -1,7 +1,7 @@
 /*  
  *  EDIT THIS FILE WITH CAUTION  (ntp-keygen-opts.c)
  *  
- *  It has been AutoGen-ed  September 29, 2011 at 08:06:17 AM by AutoGen 5.12
+ *  It has been AutoGen-ed  October  2, 2011 at 07:26:43 PM by AutoGen 5.12
  *  From the definitions    ntp-keygen-opts.def
  *  and the template file   options
  *
@@ -105,6 +105,24 @@ static char const zCertificate_Name[]        = "certificate";
 #define zCertificate_Name      NULL
 #endif  /* AUTOKEY */
 
+/*
+ *  Cipher option description:
+ */
+#ifdef AUTOKEY
+static char const zCipherText[] =
+        "privatekey cipher";
+static char const zCipher_NAME[]             = "CIPHER";
+static char const zCipher_Name[]             = "cipher";
+#define CIPHER_FLAGS       (OPTST_DISABLED \
+        | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING))
+
+#else   /* disable Cipher */
+#define CIPHER_FLAGS       (OPTST_OMITTED | OPTST_NO_INIT)
+#define zCipher_NAME      NULL
+#define zCipherText       NULL
+#define zCipher_Name      NULL
+#endif  /* AUTOKEY */
+
 /*
  *  Debug_Level option description:
  */
@@ -491,8 +509,20 @@ static tOptDesc optDesc[OPTION_CT] = {
      /* desc, NAME, name */ zCertificateText, zCertificate_NAME, zCertificate_Name,
      /* disablement strs */ NULL, NULL },
 
-  {  /* entry idx, value */ 1, VALUE_OPT_DEBUG_LEVEL,
-     /* equiv idx, value */ 1, VALUE_OPT_DEBUG_LEVEL,
+  {  /* entry idx, value */ 1, VALUE_OPT_CIPHER,
+     /* equiv idx, value */ 1, VALUE_OPT_CIPHER,
+     /* equivalenced to  */ NO_EQUIVALENT,
+     /* min, max, act ct */ 0, 1, 0,
+     /* opt state flags  */ CIPHER_FLAGS, 0,
+     /* last opt argumnt */ { NULL },
+     /* arg list/cookie  */ NULL,
+     /* must/cannot opts */ NULL, NULL,
+     /* option proc      */ NULL,
+     /* desc, NAME, name */ zCipherText, zCipher_NAME, zCipher_Name,
+     /* disablement strs */ NULL, NULL },
+
+  {  /* entry idx, value */ 2, VALUE_OPT_DEBUG_LEVEL,
+     /* equiv idx, value */ 2, VALUE_OPT_DEBUG_LEVEL,
      /* equivalenced to  */ NO_EQUIVALENT,
      /* min, max, act ct */ 0, NOLIMIT, 0,
      /* opt state flags  */ DEBUG_LEVEL_FLAGS, 0,
@@ -503,8 +533,8 @@ static tOptDesc optDesc[OPTION_CT] = {
      /* desc, NAME, name */ zDebug_LevelText, zDebug_Level_NAME, zDebug_Level_Name,
      /* disablement strs */ NULL, NULL },
 
-  {  /* entry idx, value */ 2, VALUE_OPT_SET_DEBUG_LEVEL,
-     /* equiv idx, value */ 2, VALUE_OPT_SET_DEBUG_LEVEL,
+  {  /* entry idx, value */ 3, VALUE_OPT_SET_DEBUG_LEVEL,
+     /* equiv idx, value */ 3, VALUE_OPT_SET_DEBUG_LEVEL,
      /* equivalenced to  */ NO_EQUIVALENT,
      /* min, max, act ct */ 0, NOLIMIT, 0,
      /* opt state flags  */ SET_DEBUG_LEVEL_FLAGS, 0,
@@ -515,8 +545,8 @@ static tOptDesc optDesc[OPTION_CT] = {
      /* desc, NAME, name */ zSet_Debug_LevelText, zSet_Debug_Level_NAME, zSet_Debug_Level_Name,
      /* disablement strs */ NULL, NULL },
 
-  {  /* entry idx, value */ 3, VALUE_OPT_ID_KEY,
-     /* equiv idx, value */ 3, VALUE_OPT_ID_KEY,
+  {  /* entry idx, value */ 4, VALUE_OPT_ID_KEY,
+     /* equiv idx, value */ 4, VALUE_OPT_ID_KEY,
      /* equivalenced to  */ NO_EQUIVALENT,
      /* min, max, act ct */ 0, 1, 0,
      /* opt state flags  */ ID_KEY_FLAGS, 0,
@@ -527,8 +557,8 @@ static tOptDesc optDesc[OPTION_CT] = {
      /* desc, NAME, name */ zId_KeyText, zId_Key_NAME, zId_Key_Name,
      /* disablement strs */ NULL, NULL },
 
-  {  /* entry idx, value */ 4, VALUE_OPT_GQ_PARAMS,
-     /* equiv idx, value */ 4, VALUE_OPT_GQ_PARAMS,
+  {  /* entry idx, value */ 5, VALUE_OPT_GQ_PARAMS,
+     /* equiv idx, value */ 5, VALUE_OPT_GQ_PARAMS,
      /* equivalenced to  */ NO_EQUIVALENT,
      /* min, max, act ct */ 0, 1, 0,
      /* opt state flags  */ GQ_PARAMS_FLAGS, 0,
@@ -539,8 +569,8 @@ static tOptDesc optDesc[OPTION_CT] = {
      /* desc, NAME, name */ zGq_ParamsText, zGq_Params_NAME, zGq_Params_Name,
      /* disablement strs */ NULL, NULL },
 
-  {  /* entry idx, value */ 5, VALUE_OPT_HOST_KEY,
-     /* equiv idx, value */ 5, VALUE_OPT_HOST_KEY,
+  {  /* entry idx, value */ 6, VALUE_OPT_HOST_KEY,
+     /* equiv idx, value */ 6, VALUE_OPT_HOST_KEY,
      /* equivalenced to  */ NO_EQUIVALENT,
      /* min, max, act ct */ 0, 1, 0,
      /* opt state flags  */ HOST_KEY_FLAGS, 0,
@@ -551,8 +581,8 @@ static tOptDesc optDesc[OPTION_CT] = {
      /* desc, NAME, name */ zHost_KeyText, zHost_Key_NAME, zHost_Key_Name,
      /* disablement strs */ NULL, NULL },
 
-  {  /* entry idx, value */ 6, VALUE_OPT_IFFKEY,
-     /* equiv idx, value */ 6, VALUE_OPT_IFFKEY,
+  {  /* entry idx, value */ 7, VALUE_OPT_IFFKEY,
+     /* equiv idx, value */ 7, VALUE_OPT_IFFKEY,
      /* equivalenced to  */ NO_EQUIVALENT,
      /* min, max, act ct */ 0, 1, 0,
      /* opt state flags  */ IFFKEY_FLAGS, 0,
@@ -563,8 +593,8 @@ static tOptDesc optDesc[OPTION_CT] = {
      /* desc, NAME, name */ zIffkeyText, zIffkey_NAME, zIffkey_Name,
      /* disablement strs */ NULL, NULL },
 
-  {  /* entry idx, value */ 7, VALUE_OPT_IDENT,
-     /* equiv idx, value */ 7, VALUE_OPT_IDENT,
+  {  /* entry idx, value */ 8, VALUE_OPT_IDENT,
+     /* equiv idx, value */ 8, VALUE_OPT_IDENT,
      /* equivalenced to  */ NO_EQUIVALENT,
      /* min, max, act ct */ 0, 1, 0,
      /* opt state flags  */ IDENT_FLAGS, 0,
@@ -575,8 +605,8 @@ static tOptDesc optDesc[OPTION_CT] = {
      /* desc, NAME, name */ zIdentText, zIdent_NAME, zIdent_Name,
      /* disablement strs */ NULL, NULL },
 
-  {  /* entry idx, value */ 8, VALUE_OPT_LIFETIME,
-     /* equiv idx, value */ 8, VALUE_OPT_LIFETIME,
+  {  /* entry idx, value */ 9, VALUE_OPT_LIFETIME,
+     /* equiv idx, value */ 9, VALUE_OPT_LIFETIME,
      /* equivalenced to  */ NO_EQUIVALENT,
      /* min, max, act ct */ 0, 1, 0,
      /* opt state flags  */ LIFETIME_FLAGS, 0,
@@ -587,8 +617,8 @@ static tOptDesc optDesc[OPTION_CT] = {
      /* desc, NAME, name */ zLifetimeText, zLifetime_NAME, zLifetime_Name,
      /* disablement strs */ NULL, NULL },
 
-  {  /* entry idx, value */ 9, VALUE_OPT_MD5KEY,
-     /* equiv idx, value */ 9, VALUE_OPT_MD5KEY,
+  {  /* entry idx, value */ 10, VALUE_OPT_MD5KEY,
+     /* equiv idx, value */ 10, VALUE_OPT_MD5KEY,
      /* equivalenced to  */ NO_EQUIVALENT,
      /* min, max, act ct */ 0, 1, 0,
      /* opt state flags  */ MD5KEY_FLAGS, 0,
@@ -599,8 +629,8 @@ static tOptDesc optDesc[OPTION_CT] = {
      /* desc, NAME, name */ zMd5keyText, zMd5key_NAME, zMd5key_Name,
      /* disablement strs */ NULL, NULL },
 
-  {  /* entry idx, value */ 10, VALUE_OPT_MODULUS,
-     /* equiv idx, value */ 10, VALUE_OPT_MODULUS,
+  {  /* entry idx, value */ 11, VALUE_OPT_MODULUS,
+     /* equiv idx, value */ 11, VALUE_OPT_MODULUS,
      /* equivalenced to  */ NO_EQUIVALENT,
      /* min, max, act ct */ 0, 1, 0,
      /* opt state flags  */ MODULUS_FLAGS, 0,
@@ -611,8 +641,8 @@ static tOptDesc optDesc[OPTION_CT] = {
      /* desc, NAME, name */ zModulusText, zModulus_NAME, zModulus_Name,
      /* disablement strs */ NULL, NULL },
 
-  {  /* entry idx, value */ 11, VALUE_OPT_PVT_CERT,
-     /* equiv idx, value */ 11, VALUE_OPT_PVT_CERT,
+  {  /* entry idx, value */ 12, VALUE_OPT_PVT_CERT,
+     /* equiv idx, value */ 12, VALUE_OPT_PVT_CERT,
      /* equivalenced to  */ NO_EQUIVALENT,
      /* min, max, act ct */ 0, 1, 0,
      /* opt state flags  */ PVT_CERT_FLAGS, 0,
@@ -623,8 +653,8 @@ static tOptDesc optDesc[OPTION_CT] = {
      /* desc, NAME, name */ zPvt_CertText, zPvt_Cert_NAME, zPvt_Cert_Name,
      /* disablement strs */ NULL, NULL },
 
-  {  /* entry idx, value */ 12, VALUE_OPT_PVT_PASSWD,
-     /* equiv idx, value */ 12, VALUE_OPT_PVT_PASSWD,
+  {  /* entry idx, value */ 13, VALUE_OPT_PVT_PASSWD,
+     /* equiv idx, value */ 13, VALUE_OPT_PVT_PASSWD,
      /* equivalenced to  */ NO_EQUIVALENT,
      /* min, max, act ct */ 0, 1, 0,
      /* opt state flags  */ PVT_PASSWD_FLAGS, 0,
@@ -635,8 +665,8 @@ static tOptDesc optDesc[OPTION_CT] = {
      /* desc, NAME, name */ zPvt_PasswdText, zPvt_Passwd_NAME, zPvt_Passwd_Name,
      /* disablement strs */ NULL, NULL },
 
-  {  /* entry idx, value */ 13, VALUE_OPT_GET_PVT_PASSWD,
-     /* equiv idx, value */ 13, VALUE_OPT_GET_PVT_PASSWD,
+  {  /* entry idx, value */ 14, VALUE_OPT_GET_PVT_PASSWD,
+     /* equiv idx, value */ 14, VALUE_OPT_GET_PVT_PASSWD,
      /* equivalenced to  */ NO_EQUIVALENT,
      /* min, max, act ct */ 0, 1, 0,
      /* opt state flags  */ GET_PVT_PASSWD_FLAGS, 0,
@@ -647,8 +677,8 @@ static tOptDesc optDesc[OPTION_CT] = {
      /* desc, NAME, name */ zGet_Pvt_PasswdText, zGet_Pvt_Passwd_NAME, zGet_Pvt_Passwd_Name,
      /* disablement strs */ NULL, NULL },
 
-  {  /* entry idx, value */ 14, VALUE_OPT_SIGN_KEY,
-     /* equiv idx, value */ 14, VALUE_OPT_SIGN_KEY,
+  {  /* entry idx, value */ 15, VALUE_OPT_SIGN_KEY,
+     /* equiv idx, value */ 15, VALUE_OPT_SIGN_KEY,
      /* equivalenced to  */ NO_EQUIVALENT,
      /* min, max, act ct */ 0, 1, 0,
      /* opt state flags  */ SIGN_KEY_FLAGS, 0,
@@ -659,8 +689,8 @@ static tOptDesc optDesc[OPTION_CT] = {
      /* desc, NAME, name */ zSign_KeyText, zSign_Key_NAME, zSign_Key_Name,
      /* disablement strs */ NULL, NULL },
 
-  {  /* entry idx, value */ 15, VALUE_OPT_SUBJECT_NAME,
-     /* equiv idx, value */ 15, VALUE_OPT_SUBJECT_NAME,
+  {  /* entry idx, value */ 16, VALUE_OPT_SUBJECT_NAME,
+     /* equiv idx, value */ 16, VALUE_OPT_SUBJECT_NAME,
      /* equivalenced to  */ NO_EQUIVALENT,
      /* min, max, act ct */ 0, 1, 0,
      /* opt state flags  */ SUBJECT_NAME_FLAGS, 0,
@@ -671,8 +701,8 @@ static tOptDesc optDesc[OPTION_CT] = {
      /* desc, NAME, name */ zSubject_NameText, zSubject_Name_NAME, zSubject_Name_Name,
      /* disablement strs */ NULL, NULL },
 
-  {  /* entry idx, value */ 16, VALUE_OPT_TRUSTED_CERT,
-     /* equiv idx, value */ 16, VALUE_OPT_TRUSTED_CERT,
+  {  /* entry idx, value */ 17, VALUE_OPT_TRUSTED_CERT,
+     /* equiv idx, value */ 17, VALUE_OPT_TRUSTED_CERT,
      /* equivalenced to  */ NO_EQUIVALENT,
      /* min, max, act ct */ 0, 1, 0,
      /* opt state flags  */ TRUSTED_CERT_FLAGS, 0,
@@ -683,8 +713,8 @@ static tOptDesc optDesc[OPTION_CT] = {
      /* desc, NAME, name */ zTrusted_CertText, zTrusted_Cert_NAME, zTrusted_Cert_Name,
      /* disablement strs */ NULL, NULL },
 
-  {  /* entry idx, value */ 17, VALUE_OPT_MV_PARAMS,
-     /* equiv idx, value */ 17, VALUE_OPT_MV_PARAMS,
+  {  /* entry idx, value */ 18, VALUE_OPT_MV_PARAMS,
+     /* equiv idx, value */ 18, VALUE_OPT_MV_PARAMS,
      /* equivalenced to  */ NO_EQUIVALENT,
      /* min, max, act ct */ 0, 1, 0,
      /* opt state flags  */ MV_PARAMS_FLAGS, 0,
@@ -695,8 +725,8 @@ static tOptDesc optDesc[OPTION_CT] = {
      /* desc, NAME, name */ zMv_ParamsText, zMv_Params_NAME, zMv_Params_Name,
      /* disablement strs */ NULL, NULL },
 
-  {  /* entry idx, value */ 18, VALUE_OPT_MV_KEYS,
-     /* equiv idx, value */ 18, VALUE_OPT_MV_KEYS,
+  {  /* entry idx, value */ 19, VALUE_OPT_MV_KEYS,
+     /* equiv idx, value */ 19, VALUE_OPT_MV_KEYS,
      /* equivalenced to  */ NO_EQUIVALENT,
      /* min, max, act ct */ 0, 1, 0,
      /* opt state flags  */ MV_KEYS_FLAGS, 0,
@@ -851,7 +881,7 @@ tOptions ntp_keygenOptions = {
       NO_EQUIVALENT, /* '-#' option index */
       NO_EQUIVALENT /* index of default opt */
     },
-    24 /* full option count */, 19 /* user option count */,
+    25 /* full option count */, 20 /* user option count */,
     ntp_keygen_full_usage, ntp_keygen_short_usage,
     NULL, NULL,
     PKGDATADIR, ntp_keygen_packager_info
index 9aa596ca11bf823cadb412db1d443420d48534b4..ab59fbcac4745c007e9933ac01d34751386df0d6 100644 (file)
@@ -167,7 +167,7 @@ flag = {
     descrip   = "output private password";
     doc = <<-  _EndOfDoc_
        Encrypt generated files containing private data with the specified
-       password and the DES-CBC algorithm.
+       password and the cipher selected with -C/--cipher.
        _EndOfDoc_;
 };
 
index 2d92e0d0c89a09c8552fea9e00fcdc1a5c798f27..d56bae94fbab9b716fd3ae0f643dbe75a41377b2 100644 (file)
@@ -1,7 +1,7 @@
 /*  
  *  EDIT THIS FILE WITH CAUTION  (ntp-keygen-opts.h)
  *  
- *  It has been AutoGen-ed  September 29, 2011 at 08:06:17 AM by AutoGen 5.12
+ *  It has been AutoGen-ed  October  2, 2011 at 07:26:43 PM by AutoGen 5.12
  *  From the definitions    ntp-keygen-opts.def
  *  and the template file   options
  *
@@ -64,32 +64,33 @@ PFX>Permission to use, copy, modify, and distribute this software and its
  */
 typedef enum {
     INDEX_OPT_CERTIFICATE      =  0,
-    INDEX_OPT_DEBUG_LEVEL      =  1,
-    INDEX_OPT_SET_DEBUG_LEVEL  =  2,
-    INDEX_OPT_ID_KEY           =  3,
-    INDEX_OPT_GQ_PARAMS        =  4,
-    INDEX_OPT_HOST_KEY         =  5,
-    INDEX_OPT_IFFKEY           =  6,
-    INDEX_OPT_IDENT            =  7,
-    INDEX_OPT_LIFETIME         =  8,
-    INDEX_OPT_MD5KEY           =  9,
-    INDEX_OPT_MODULUS          = 10,
-    INDEX_OPT_PVT_CERT         = 11,
-    INDEX_OPT_PVT_PASSWD       = 12,
-    INDEX_OPT_GET_PVT_PASSWD   = 13,
-    INDEX_OPT_SIGN_KEY         = 14,
-    INDEX_OPT_SUBJECT_NAME     = 15,
-    INDEX_OPT_TRUSTED_CERT     = 16,
-    INDEX_OPT_MV_PARAMS        = 17,
-    INDEX_OPT_MV_KEYS          = 18,
-    INDEX_OPT_VERSION          = 19,
-    INDEX_OPT_HELP             = 20,
-    INDEX_OPT_MORE_HELP        = 21,
-    INDEX_OPT_SAVE_OPTS        = 22,
-    INDEX_OPT_LOAD_OPTS        = 23
+    INDEX_OPT_CIPHER           =  1,
+    INDEX_OPT_DEBUG_LEVEL      =  2,
+    INDEX_OPT_SET_DEBUG_LEVEL  =  3,
+    INDEX_OPT_ID_KEY           =  4,
+    INDEX_OPT_GQ_PARAMS        =  5,
+    INDEX_OPT_HOST_KEY         =  6,
+    INDEX_OPT_IFFKEY           =  7,
+    INDEX_OPT_IDENT            =  8,
+    INDEX_OPT_LIFETIME         =  9,
+    INDEX_OPT_MD5KEY           = 10,
+    INDEX_OPT_MODULUS          = 11,
+    INDEX_OPT_PVT_CERT         = 12,
+    INDEX_OPT_PVT_PASSWD       = 13,
+    INDEX_OPT_GET_PVT_PASSWD   = 14,
+    INDEX_OPT_SIGN_KEY         = 15,
+    INDEX_OPT_SUBJECT_NAME     = 16,
+    INDEX_OPT_TRUSTED_CERT     = 17,
+    INDEX_OPT_MV_PARAMS        = 18,
+    INDEX_OPT_MV_KEYS          = 19,
+    INDEX_OPT_VERSION          = 20,
+    INDEX_OPT_HELP             = 21,
+    INDEX_OPT_MORE_HELP        = 22,
+    INDEX_OPT_SAVE_OPTS        = 23,
+    INDEX_OPT_LOAD_OPTS        = 24
 } teOptIndex;
 
-#define OPTION_CT    24
+#define OPTION_CT    25
 #define NTP_KEYGEN_VERSION       "4.2.7p217"
 #define NTP_KEYGEN_FULL_VERSION  "ntp-keygen (ntp) 4.2.7p217"
 
@@ -130,6 +131,10 @@ typedef enum {
 #  warning undefining CERTIFICATE due to option name conflict
 #  undef   CERTIFICATE
 # endif
+# ifdef    CIPHER
+#  warning undefining CIPHER due to option name conflict
+#  undef   CIPHER
+# endif
 # ifdef    DEBUG_LEVEL
 #  warning undefining DEBUG_LEVEL due to option name conflict
 #  undef   DEBUG_LEVEL
@@ -204,6 +209,7 @@ typedef enum {
 # endif
 #else  /* NO_OPTION_NAME_WARNINGS */
 # undef CERTIFICATE
+# undef CIPHER
 # undef DEBUG_LEVEL
 # undef SET_DEBUG_LEVEL
 # undef ID_KEY
@@ -229,6 +235,7 @@ typedef enum {
  *  Interface defines for specific options.
  */
 #define VALUE_OPT_CERTIFICATE    'c'
+#define VALUE_OPT_CIPHER         'C'
 #define VALUE_OPT_DEBUG_LEVEL    'd'
 #define VALUE_OPT_SET_DEBUG_LEVEL 'D'
 #define VALUE_OPT_ID_KEY         'e'
index 5d65e93541d46036d72abceb5c12991c0455e723..4301e362575454bb37be6abb28ef6be962e57ee9 100644 (file)
@@ -180,23 +180,66 @@ const EVP_CIPHER * cipher = NULL;
 BOOL init_randfile();
 
 /*
- * Don't try to follow symbolic links.  Assumes link == file.
+ * Don't try to follow symbolic links on Windows.  Assume link == file.
  */
 int
-readlink(char *link, char *file, int len)
+readlink(
+       char *  link,
+       char *  file,
+       int     len
+       )
 {
        return strlen(file);
 }
 
 /*
- * Don't try to create a symbolic link for now.
- * Just move the file to the name you need.
+ * Don't try to create symbolic links on Windows, that is supported on
+ * Vista and later only.  Instead, if CreateHardLink is available (XP
+ * and later), hardlink the linkname to the original filename.  On
+ * earlier systems, user must rename file to match expected link for
+ * ntpd to find it.  To allow building a ntp-keygen.exe which loads on
+ * Windows pre-XP, runtime link to CreateHardLinkA().
  */
 int
-symlink(char *filename, char *linkname) {
-       DeleteFile(linkname);
-       MoveFile(filename, linkname);
-       return (0);
+symlink(
+       char *  filename,
+       char*   linkname
+       )
+{
+       typedef BOOL (WINAPI *PCREATEHARDLINKA)(
+               __in LPCSTR     lpFileName,
+               __in LPCSTR     lpExistingFileName,
+               __reserved LPSECURITY_ATTRIBUTES lpSA
+               );
+       static PCREATEHARDLINKA pCreateHardLinkA;
+       static int              tried;
+       HMODULE                 hDll;
+       FARPROC                 pfn;
+       int                     link_created;
+       int                     saved_errno;
+
+       if (!tried) {
+               tried = TRUE;
+               hDll = LoadLibrary("kernel32.dll");
+               pfn = GetProcAddress(hDll, "CreateHardLinkA");
+               pCreateHardLinkA = (PCREATEHARDLINKA)pfn;
+       }
+
+       if (NULL == pCreateHardLinkA) {
+               errno = ENOSYS;
+               return -1;
+       }
+
+       link_created = (*pCreateHardLinkA)(linkname, filename, NULL);
+       
+       if (link_created)
+               return 0;
+
+       saved_errno = GetLastError();   /* yes we play loose */
+       mfprintf(stderr, "Create hard link %s to %s failed: %m\n",
+                linkname, filename);
+       errno = saved_errno;
+       return -1;
 }
 
 void
@@ -588,9 +631,9 @@ main(
                BN_copy(rsa->q, BN_value_one());
                pkey = EVP_PKEY_new();
                EVP_PKEY_assign_RSA(pkey, rsa);
-               PEM_write_PrivateKey(stdout, pkey, NULL, NULL, 0, NULL,
-                   NULL);
-               fclose(stdout);
+               PEM_write_PKCS8PrivateKey(stdout, pkey, NULL, NULL, 0,
+                   NULL, NULL);
+               fflush(stdout);
                if (debug)
                        RSA_print_fp(stderr, rsa, 0);
        }
@@ -610,9 +653,9 @@ main(
                rsa = pkey_gqkey->pkey.rsa;
                pkey = EVP_PKEY_new();
                EVP_PKEY_assign_RSA(pkey, rsa);
-               PEM_write_PrivateKey(stdout, pkey,
-                   cipher, NULL, 0, NULL, passwd2);
-               fclose(stdout);
+               PEM_write_PKCS8PrivateKey(stdout, pkey, cipher, NULL, 0,
+                   NULL, passwd2);
+               fflush(stdout);
                if (debug)
                        RSA_print_fp(stderr, rsa, 0);
        }
@@ -652,9 +695,9 @@ main(
                BN_copy(dsa->priv_key, BN_value_one());
                pkey = EVP_PKEY_new();
                EVP_PKEY_assign_DSA(pkey, dsa);
-               PEM_write_PrivateKey(stdout, pkey, NULL, NULL, 0, NULL,
-                   NULL);
-               fclose(stdout);
+               PEM_write_PKCS8PrivateKey(stdout, pkey, NULL, NULL, 0,
+                   NULL, NULL);
+               fflush(stdout);
                if (debug)
                        DSA_print_fp(stderr, dsa, 0);
        }
@@ -674,9 +717,9 @@ main(
                dsa = pkey_iffkey->pkey.dsa;
                pkey = EVP_PKEY_new();
                EVP_PKEY_assign_DSA(pkey, dsa);
-               PEM_write_PrivateKey(stdout, pkey, cipher, NULL,
-                   0, NULL, passwd2);
-               fclose(stdout);
+               PEM_write_PKCS8PrivateKey(stdout, pkey, cipher, NULL, 0,
+                   NULL, passwd2);
+               fflush(stdout);
                if (debug)
                        DSA_print_fp(stderr, dsa, 0);
        }
@@ -712,9 +755,9 @@ main(
                fprintf(stdout, "# %s\n# %s\n", filename,
                    ctime(&epoch));
                pkey = pkey_mvpar[2];
-               PEM_write_PrivateKey(stdout, pkey, NULL, NULL, 0, NULL,
-                   NULL);
-               fclose(stdout);
+               PEM_write_PKCS8PrivateKey(stdout, pkey, NULL, NULL, 0,
+                   NULL, NULL);
+               fflush(stdout);
                if (debug)
                        DSA_print_fp(stderr, pkey->pkey.dsa, 0);
        }
@@ -730,9 +773,9 @@ main(
                fprintf(stdout, "# %s\n# %s\n", filename,
                    ctime(&epoch));
                pkey = pkey_mvpar[1];
-               PEM_write_PrivateKey(stdout, pkey, cipher, NULL,
-                   0, NULL, passwd2);
-               fclose(stdout);
+               PEM_write_PKCS8PrivateKey(stdout, pkey, cipher, NULL, 0,
+                   NULL, passwd2);
+               fflush(stdout);
                if (debug)
                        DSA_print_fp(stderr, pkey->pkey.dsa, 0);
        }
@@ -941,7 +984,7 @@ gen_rsa(
                str = fheader("RSAhost", id, hostname);
        pkey = EVP_PKEY_new();
        EVP_PKEY_assign_RSA(pkey, rsa);
-       PEM_write_PrivateKey(str, pkey, cipher, NULL, 0, NULL,
+       PEM_write_PKCS8PrivateKey(str, pkey, cipher, NULL, 0, NULL,
            passwd1);
        fclose(str);
        if (debug)
@@ -996,7 +1039,7 @@ gen_dsa(
        str = fheader("DSAsign", id, hostname);
        pkey = EVP_PKEY_new();
        EVP_PKEY_assign_DSA(pkey, dsa);
-       PEM_write_PrivateKey(str, pkey, cipher, NULL, 0, NULL,
+       PEM_write_PKCS8PrivateKey(str, pkey, cipher, NULL, 0, NULL,
            passwd1);
        fclose(str);
        if (debug)
@@ -1163,7 +1206,7 @@ gen_iffkey(
        str = fheader("IFFkey", id, groupname);
        pkey = EVP_PKEY_new();
        EVP_PKEY_assign_DSA(pkey, dsa);
-       PEM_write_PrivateKey(str, pkey, cipher, NULL, 0, NULL,
+       PEM_write_PKCS8PrivateKey(str, pkey, cipher, NULL, 0, NULL,
            passwd1);
        fclose(str);
        if (debug)
@@ -1360,7 +1403,7 @@ gen_gqkey(
        str = fheader("GQkey", id, groupname);
        pkey = EVP_PKEY_new();
        EVP_PKEY_assign_RSA(pkey, rsa);
-       PEM_write_PrivateKey(str, pkey, EVP_des_cbc(), NULL, 0, NULL,
+       PEM_write_PKCS8PrivateKey(str, pkey, cipher, NULL, 0, NULL,
            passwd1);
        fclose(str);
        if (debug)
@@ -1762,7 +1805,7 @@ gen_mvkey(
        BN_copy(dsa->pub_key, b);
        pkey = EVP_PKEY_new();
        EVP_PKEY_assign_DSA(pkey, dsa);
-       PEM_write_PrivateKey(str, pkey, EVP_des_cbc(), NULL, 0, NULL,
+       PEM_write_PKCS8PrivateKey(str, pkey, cipher, NULL, 0, NULL,
            passwd1);
        evpars[i++] = pkey;
        if (debug)
@@ -1788,7 +1831,7 @@ gen_mvkey(
        dsa2->pub_key = BN_dup(ghat);
        pkey1 = EVP_PKEY_new();
        EVP_PKEY_assign_DSA(pkey1, dsa2);
-       PEM_write_PrivateKey(str, pkey1, EVP_des_cbc(), NULL, 0, NULL,
+       PEM_write_PKCS8PrivateKey(str, pkey1, cipher, NULL, 0, NULL,
            passwd1);
        evpars[i++] = pkey1;
        if (debug)
@@ -1813,7 +1856,7 @@ gen_mvkey(
                sdsa->pub_key = BN_dup(xhat[j]);
                pkey1 = EVP_PKEY_new();
                EVP_PKEY_set1_DSA(pkey1, sdsa);
-               PEM_write_PrivateKey(str, pkey1, EVP_des_cbc(), NULL, 0,
+               PEM_write_PKCS8PrivateKey(str, pkey1, cipher, NULL, 0,
                    NULL, passwd1);
                evpars[i++] = pkey1;
                if (debug)
@@ -1866,8 +1909,8 @@ gen_mvkey(
  */
 int
 x509   (
-       EVP_PKEY *pkey,         /* generic signature algorithm */
-       const EVP_MD *md,       /* generic digest algorithm */
+       EVP_PKEY *pkey,         /* signing key */
+       const EVP_MD *md,       /* signature/digest scheme */
        char    *gqpub,         /* identity extension (hex string) */
        char    *exten,         /* private cert extension */
        char    *name           /* subject/issuer name */
@@ -1900,12 +1943,12 @@ x509    (
        X509_time_adj(X509_get_notAfter(cert), lifetime * DAY, &epoch);
        subj = X509_get_subject_name(cert);
        X509_NAME_add_entry_by_txt(subj, "commonName", MBSTRING_ASC,
-           (unsigned char *) name, strlen(name), -1, 0);
+           (u_char *)name, strlen(name), -1, 0);
        subj = X509_get_issuer_name(cert);
        X509_NAME_add_entry_by_txt(subj, "commonName", MBSTRING_ASC,
-           (unsigned char *) name, strlen(name), -1, 0);
+           (u_char *)name, strlen(name), -1, 0);
        if (!X509_set_pubkey(cert, pkey)) {
-               fprintf(stderr, "Assign key fails\n%s\n",
+               fprintf(stderr, "Assign certificate signing key fails\n%s\n",
                    ERR_error_string(ERR_get_error(), NULL));
                X509_free(cert);
                return (0);