Golang utf16le encoding for ldap password attribute - go

I'm trying to reset a MS Active Directory password attribute using ldap in Go. AD won't play nicely with ldap.PasswordModifyRequest so I'm using ldap.NewModifyRequest. (Using gopkg.in/ldap.v2)
AD will accept the password surrounded in quotes and utf16le encoded, in Python I can do this using
unicode_pass = unicode("\"secret\"", "iso-8859-1")
password_value = unicode_pass.encode("utf-16-le")
mod_attrs = [(ldap.MOD_REPLACE, "unicodePwd", [password_value])]
l.modify_s(user_dn, mod_attrs)
How can I do this in Go? Using ldap.NewModifyRequest and Replace I can change other attributes, but I need to pass Request []string for the updated value, that needs to be my encoded password, and I'm running into type mismatches when I play around with utf16.Encode...
modify := ldap.NewModifyRequest(dn)
modify.Replace("unicodePwd", []string{"encodedsecret"})
Thanks.

You can use the golang.org/x/text/encoding/unicode package to encode your string as UTF16.
Using this package you can write something like this:
utf16 := unicode.UTF16(unicode.LittleEndian, unicode.IgnoreBOM)
encoded, err := utf16.NewEncoder().String("encodedsecret")
modify := ldap.NewModifyRequest(dn)
modify.Replace("unicodePwd", []string{encoded})
// do something with modify

Related

Json response in Go(Gin) without escape characters

I have recently started working on Go APIs using GIN. My API is getting the data from DB with two columns where one column contains integer and other contains a json string.
The json string is dynamic and hence i cant use struct for that.
I am using map[string]interface{} to parse the json and modify it and then parse it back to json using json.Marshal. Now i am returning this json string as a response but getting escape characters. Have done some search regarding that, but didnt find any solution yet.
Here is the part of code that i am using
var interface_obj map[string]interface{}
json.Unmarshal([]byte(grants.Data), &interface_obj)
grants_map := interface_obj["role_grants"].(map[string]interface{})
jsonString, err := json.Marshal(grants_map)
jsonBody := string(jsonString)
After this, I am returning this JSON as response in GIN framework like this
c.JSON(http.StatusCreated, gin.H{"message": "Json retrieved successfully", "data": jsonBody})
But the output i am getting is
{
"data": "[{\"action\":\"read\",\"resource\":\"project\"},{\"action\":\"all\",\"resource\":\"users\"},{\"action\":\"all\",\"resource\":\"roles\"},{\"action\":\"all\",\"resource\":\"project-settings\"},{\"action\":\"create\",\"resource\":\"single-entity-screening\"},{\"action\":\"read\",\"resource\":\"single-entity-screening\"},{\"action\":\"create\",\"resource\":\"multi-batch-screening\"},{\"action\":\"read\",\"resource\":\"multi-batch-screening\"},{\"action\":\"read\",\"resource\":\"workspace\"},{\"action\":\"allocate\",\"resource\":\"workspace\"},{\"action\":\"update\",\"resource\":\"workspace\"},{\"action\":\"read\",\"resource\":\"case\"},{\"action\":\"allocate\",\"resource\":\"case\"},{\"action\":\"review\",\"resource\":\"case\"},{\"action\":\"update\",\"resource\":\"case\"},{\"action\":\"read\",\"resource\":\"report\"},{\"action\":\"read\",\"resource\":\"audit-trail\"},{\"action\":\"read\",\"resource\":\"delivery\"}]",
"message": "Grants retrieved successfully"
}
I printed it on my console and it looked fine there, but causing this issue on response.
Is there any way to resolve this using some standard way? Please guide
Thanks
You don't need to do json.Marshal(grants_map), just pass the value directly to gin.H and let c.JSON do the encoding, i.e.
gin.H{... "data": grants_map}
And in cases where you truly have raw JSON data at hand that you want to send as part of other not-yet-JSON data, you can wrap it into json.RawMessage to avoid the "double-encoding", i.e.
gin.H{... "data": json.RawMessage(jsonBody)}

Substitute a variable in regexp.MatchString method

I have a golang script that needs to create and look for a particular regex. The string to look for id defined as a constant.
const nameRegex = "service-route"
I can use this variable in some places.
rb := &compute.Route{
Name: fmt.Sprintf("%s-%s", nameRegex, generateCode(host))
I would like to use the same string to find aswell.
Basically I have something like
matched, _ := regexp.MatchString("^service-route-.*", route.Name)
if matched {
Doing something like
matched, _ := regexp.MatchString("^%s-.*" , nameRegex, route.Name)
does not work as the function MatchString requires only 1 argument.
I tried something like
myRegex , err := regexp.Compile("%s", nameRegex)
myRegex.MatchString(route.Name)
that too does not work.
Is it even possible to use a variable to match a regex ?
The 1st parameter to MatchString is a string. So use Sprintf (as you did earlier) to generate the pattern string, something like this:
regexp.MatchString(fmt.Sprintf("^%s-.*", nameRegex), route.Name)
or construct the string using concatentation:
regexp.MatchString("^" + nameRegex + "-.*", route.Name)
This seems to be a one-off check, so there is not need to pre-compile the regex.
It is possible. Here is go playground : https://play.golang.org/p/hc9eMcSzGQC

Non-escaped query parameters for URL

I want to create a query parameter without escaping the query string.
For example, I need to create a query parameter q with the content
"before:{2019-12-24 19:57:34}"
so that the URL is
https://android-review.googlesource.com/changes/?q=before:{2019-12-24 19:57:34}
If I use this code (Golang Playground)
url, _ := url.Parse("https://android-review.googlesource.com/changes/")
q := url.Query()
q.Set("q", "before:{2019-12-24 19:57:34}")
url.RawQuery = q.Encode()
fmt.Println(url)
url is escaping the special characters, spaces, and brackets:
https://android-review.googlesource.com/changes/?q=before%3A%7B2019-12-24+19%3A57%3A34%7D
How can I solve this issue except manually creating the URL (without query parameters then)?
If you don't want your URL query to be encoded, then don't use the Encode() method. Instead, set the RawQuery value directly, yourself:
url, _ := url.Parse("https://android-review.googlesource.com/changes/")
url.RawQuery = "q=before:{2019-12-24 19:57:34}"
fmt.Println(url)
Output:
https://android-review.googlesource.com/changes/?q=before:{2019-12-24 19:57:34}
playground
Keep in mind, however, that this is a recipe for potential disaster, depending on how that url is eventually used. In particular, the space in that URL should be escaped, according to RFC. See more here.
Perhaps you'll want to implement your own minimal escaping, if that's compatible with your use-case.

Can "token" generated using "Paseto Token" be decrypted and viewed like "JWT Token"?

I am using "Platform agnostic Security Token" for oAuth in Golang - https://github.com/o1egl/paseto
I am not able to understand, why this is better than JWT even after reading README
My Major Question is:
Can "token" generated be altered like "JWT" and pass modified or tampered data?
Can "token" generated using "paseto" be decrypted and viewed like "JWT"?
Paseto library above uses "SET" and "GET" method inside their JSONToken method. Is that how we can verify authenticity of the user?
Sample Code:
symmetricKey := []byte("YELLOW SUBMARINE, BLACK WIZARDRY") // Must be 32 bytes
now := time.Now()
exp := now.Add(24 * time.Hour)
nbt := now
jsonToken := paseto.JSONToken{
Audience: "test",
Issuer: "test_service",
Jti: "123",
Subject: "test_subject",
IssuedAt: now,
Expiration: exp,
NotBefore: nbt,
}
// Add custom claim to the token
jsonToken.Set("data", "this is a signed message")
footer := "some footer"
v2 := paseto.NewV2()
// Encrypt data
token, err := v2.Encrypt(symmetricKey, jsonToken, footer)
// token = "v2.local.E42A2iMY9SaZVzt-WkCi45_aebky4vbSUJsfG45OcanamwXwieieMjSjUkgsyZzlbYt82miN1xD-X0zEIhLK_RhWUPLZc9nC0shmkkkHS5Exj2zTpdNWhrC5KJRyUrI0cupc5qrctuREFLAvdCgwZBjh1QSgBX74V631fzl1IErGBgnt2LV1aij5W3hw9cXv4gtm_jSwsfee9HZcCE0sgUgAvklJCDO__8v_fTY7i_Regp5ZPa7h0X0m3yf0n4OXY9PRplunUpD9uEsXJ_MTF5gSFR3qE29eCHbJtRt0FFl81x-GCsQ9H9701TzEjGehCC6Bhw.c29tZSBmb290ZXI"
// Decrypt data
var newJsonToken paseto.JSONToken
var newFooter string
err := v2.Decrypt(token, symmetricKey, &newJsonToken, &newFooter)
Now, if you see there is code: jsonToken.Set("data", "this is a signed message") and we can get that value in Decrypt data at the end where newJsonToken variable is created.
We can get the value of "data" key using: newJsonToken.Get("data").
But is above data "verifiable" and can't be tampered or modified on user's end?
Like in JWT debugger at JWT.io, People can tamper data and know the algorithm and pass "modified" data.
Can user do the same with my generated token as well? Can they decode and pass tampered data? or they can't decode data or view actual data at all?
1 - Can "token" generated be altered like "JWT" and pass modified or tampered data?
Note that token cannot be "altered" either using PASETO or JWT without knowing the signing key (which should of course be secret).
The fact you mention about being able to view the JWT token data in JWT.io page is because data is not encrypted (so you can see it without the key).
But token is signed, so if you modify any value and don't have the key, you won't be able to sign it back and the token receiver will note the token is not valid when trying to verify it.
2 - Can "token" generated using "paseto" be decrypted and viewed like "JWT"?
It depends on how you generate the PASETO token.
See here:
https://tools.ietf.org/id/draft-paragon-paseto-rfc-00.html#rfc.section.2
Format for the token is version.purpose.payload.
And from the docs:
The payload is a string that contains the token's data. In a local token, this data is encrypted with a symmetric cipher. In a public token, this data is unencrypted.
So if you generate the token as in the code snippet you posted (local token, with a symmetric key), then payload will be encrypted (you won't be able to see it unless you know the symmetric key and use that one to decrypt it).
If you use a public/private key pair, then payload will not be encrypted, so you'll be able to see it without the key (but you'll not be able to change it and sign it again without knowing the private key).

http.NewRequest() decoding my URL input

When using http.NewRequest("GET", url , nil) for URLs that contain a % followed by some number, *example: https://api.deutschebahn.com/freeplan/v1/journeyDetails/356418%252F128592%252F57070%252F90271%252F80%253fstation_evaId%253D8000261) Go will encode the string to a "/" in the url. How can I avoid that?
Explicitly set the RawPath field of the URL struct:
req := http.NewRequest("GET", "https://api.deutschebahn.com/freeplan/v1/journeyDetails/356418%252F128592%252F57070%252F90271%252F80%253fstation_evaId%253D8000261", nil)
req.URL.RawPath = "/freeplan/v1/journeyDetails/356418%252F128592%252F57070%252F90271%252F80%253fstation_evaId%253D8000261"
This functionality is documented for this use case:
Note that the Path field is stored in decoded form: /%47%6f%2f becomes /Go/. A consequence is that it is impossible to tell which slashes in the Path were slashes in the raw URL and which were %2f. This distinction is rarely important, but when it is, code must not use Path directly.
Go 1.5 introduced the RawPath field to hold the encoded form of Path. The Parse function sets both Path and RawPath in the URL it returns, and URL's String method uses RawPath if it is a valid encoding of Path, by calling the EscapedPath method.

Resources