func win32TimeFromTar(key string, hdrs map[string]string, unixTime time.Time) syscall.Filetime { if s, ok := hdrs[key]; ok { n, err := strconv.ParseUint(s, 10, 64) if err == nil { return syscall.Filetime{uint32(n & 0xffffffff), uint32(n >> 32)} } } return syscall.NsecToFiletime(unixTime.UnixNano()) }
// FileInfoFromHeader retrieves basic Win32 file information from a tar header, using the additional metadata written by // WriteTarFileFromBackupStream. func FileInfoFromHeader(hdr *tar.Header) (name string, size int64, fileInfo *winio.FileBasicInfo, err error) { name = hdr.Name if hdr.Typeflag == tar.TypeReg || hdr.Typeflag == tar.TypeRegA { size = hdr.Size } fileInfo = &winio.FileBasicInfo{ LastAccessTime: syscall.NsecToFiletime(hdr.AccessTime.UnixNano()), LastWriteTime: syscall.NsecToFiletime(hdr.ModTime.UnixNano()), ChangeTime: syscall.NsecToFiletime(hdr.ChangeTime.UnixNano()), CreationTime: syscall.NsecToFiletime(hdr.CreationTime.UnixNano()), } if attrStr, ok := hdr.Winheaders[hdrFileAttributes]; ok { attr, err := strconv.ParseUint(attrStr, 10, 32) if err != nil { return "", 0, nil, err } fileInfo.FileAttributes = uintptr(attr) } else { if hdr.Typeflag == tar.TypeDir { fileInfo.FileAttributes |= syscall.FILE_ATTRIBUTE_DIRECTORY } } return }
//setCTime will set the create time on a file. On Windows, this requires //calling SetFileTime and explicitly including the create time. func setCTime(path string, ctime time.Time) error { ctimespec := syscall.NsecToTimespec(ctime.UnixNano()) pathp, e := syscall.UTF16PtrFromString(path) if e != nil { return e } h, e := syscall.CreateFile(pathp, syscall.FILE_WRITE_ATTRIBUTES, syscall.FILE_SHARE_WRITE, nil, syscall.OPEN_EXISTING, syscall.FILE_FLAG_BACKUP_SEMANTICS, 0) if e != nil { return e } defer syscall.Close(h) c := syscall.NsecToFiletime(syscall.TimespecToNsec(ctimespec)) return syscall.SetFileTime(h, &c, nil, nil) }
// Convert the given Credential object back to a CREDENTIAL struct, which can be used for calling the // Windows APIs func nativeFromCredential(cred *Credential) (result *nativeCREDENTIAL) { result = new(nativeCREDENTIAL) result.Flags = 0 result.Type = 0 result.TargetName, _ = syscall.UTF16PtrFromString(cred.TargetName) result.Comment, _ = syscall.UTF16PtrFromString(cred.Comment) result.LastWritten = syscall.NsecToFiletime(cred.LastWritten.UnixNano()) result.CredentialBlobSize = uint32(len(cred.CredentialBlob)) if len(cred.CredentialBlob) > 0 { result.CredentialBlob = uintptr(unsafe.Pointer(&cred.CredentialBlob[0])) } else { result.CredentialBlob = 0 } result.Persist = uint32(cred.Persist) result.AttributeCount = uint32(len(cred.Attributes)) attributes := make([]nativeCREDENTIAL_ATTRIBUTE, len(cred.Attributes)) if len(attributes) > 0 { result.Attributes = uintptr(unsafe.Pointer(&attributes[0])) } else { result.Attributes = 0 } for i, _ := range cred.Attributes { inAttr := &cred.Attributes[i] outAttr := &attributes[i] outAttr.Keyword, _ = syscall.UTF16PtrFromString(inAttr.Keyword) outAttr.Flags = 0 outAttr.ValueSize = uint32(len(inAttr.Value)) if len(inAttr.Value) > 0 { outAttr.Value = uintptr(unsafe.Pointer(&inAttr.Value[0])) } else { outAttr.Value = 0 } } result.TargetAlias, _ = syscall.UTF16PtrFromString(cred.TargetAlias) result.UserName, _ = syscall.UTF16PtrFromString(cred.UserName) return }
func getFileTime() syscall.Filetime { loc, _ := time.LoadLocation("Asia/Shanghai") st, err := time.ParseInLocation(LongTimeFormat, "2014-06-23 10:09:29", loc) if err != nil { fmt.Println(err) } et, err := time.ParseInLocation(LongTimeFormat, "2014-06-23 10:09:30", loc) if err != nil { fmt.Println(err) } gapTimestamp := et.Unix() - st.Unix() rand.Seed(time.Now().UnixNano()) randGap := rand.Int63n(gapTimestamp) distTime := uniformTime(time.Unix(st.Unix()+randGap, 0)) ftime := syscall.NsecToFiletime(distTime.UnixNano()) return ftime }
// systemVerify is like Verify, except that it uses CryptoAPI calls // to build certificate chains and verify them. func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Certificate, err error) { hasDNSName := opts != nil && len(opts.DNSName) > 0 storeCtx, err := createStoreContext(c, opts) if err != nil { return nil, err } defer syscall.CertFreeCertificateContext(storeCtx) para := new(syscall.CertChainPara) para.Size = uint32(unsafe.Sizeof(*para)) // If there's a DNSName set in opts, assume we're verifying // a certificate from a TLS server. if hasDNSName { oids := []*byte{ &syscall.OID_PKIX_KP_SERVER_AUTH[0], // Both IE and Chrome allow certificates with // Server Gated Crypto as well. Some certificates // in the wild require them. &syscall.OID_SERVER_GATED_CRYPTO[0], &syscall.OID_SGC_NETSCAPE[0], } para.RequestedUsage.Type = syscall.USAGE_MATCH_TYPE_OR para.RequestedUsage.Usage.Length = uint32(len(oids)) para.RequestedUsage.Usage.UsageIdentifiers = &oids[0] } else { para.RequestedUsage.Type = syscall.USAGE_MATCH_TYPE_AND para.RequestedUsage.Usage.Length = 0 para.RequestedUsage.Usage.UsageIdentifiers = nil } var verifyTime *syscall.Filetime if opts != nil && !opts.CurrentTime.IsZero() { ft := syscall.NsecToFiletime(opts.CurrentTime.UnixNano()) verifyTime = &ft } // CertGetCertificateChain will traverse Windows's root stores // in an attempt to build a verified certificate chain. Once // it has found a verified chain, it stops. MSDN docs on // CERT_CHAIN_CONTEXT: // // When a CERT_CHAIN_CONTEXT is built, the first simple chain // begins with an end certificate and ends with a self-signed // certificate. If that self-signed certificate is not a root // or otherwise trusted certificate, an attempt is made to // build a new chain. CTLs are used to create the new chain // beginning with the self-signed certificate from the original // chain as the end certificate of the new chain. This process // continues building additional simple chains until the first // self-signed certificate is a trusted certificate or until // an additional simple chain cannot be built. // // The result is that we'll only get a single trusted chain to // return to our caller. var chainCtx *syscall.CertChainContext err = syscall.CertGetCertificateChain(syscall.Handle(0), storeCtx, verifyTime, storeCtx.Store, para, 0, 0, &chainCtx) if err != nil { return nil, err } defer syscall.CertFreeCertificateChain(chainCtx) err = checkChainTrustStatus(c, chainCtx) if err != nil { return nil, err } if hasDNSName { err = checkChainSSLServerPolicy(c, chainCtx, opts) if err != nil { return nil, err } } chain, err := extractSimpleChain(chainCtx.Chains, int(chainCtx.ChainCount)) if err != nil { return nil, err } chains = append(chains, chain) return chains, nil }