NetTalk Central

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - bshields

Pages: [1] 2 3 ... 25
1
Web Server - Ask For Help / Re: json format in post data
« on: August 16, 2021, 04:00:10 AM »
Hi Jason,

Use {{ to escape the single { in clarion code.

Don't do it for }

Regards
Bill

2
Web Server - Ask For Help / Re: How to be a consultant?
« on: July 25, 2021, 06:38:10 PM »
Hi Jeff,

Sure.

bshields at inhabit.com.au

My mobile is 0410884907

Regards
Bill

3
Web Server - Ask For Help / Re: JWT Json Web Token
« on: July 22, 2021, 12:36:42 AM »
Hi Bruce,

Awesome! Thanks. I'll clean up my code.

Regards
Bill

4
Web Server - Ask For Help / Re: JWT Json Web Token
« on: July 21, 2021, 03:19:36 AM »
Hi Jason,

I thought I should post the solution here incase anyone was interested (after we worked through it on Slack).

TestVonage           PROCEDURE                             ! Declare Procedure
lToken   STRING(1024)
lPayload STRING(1024)
lSecret  STRING(255)
lAPIKey  STRING(255)
  CODE
  lSecret = 'b845bb0a8b2xxxxxxxxxxxxxx30c108da7bd755b'
  lAPIKey = 'xxxxxxx'
  lPayload = '{{"iss": "'&CLIP(lAPIKey)&'","iat": '&TimestampZ()&',"exp": '&TimestampZ()+180&',"ist": "Inhabit","jti": "'&RandomString(16)&'"}'
  lToken = CreateJWTToken(CLIP(lPayload),CLIP(lSecret))
  WriteDebugInfo('Payload: '&CLIP(lPayload))
  WriteDebugInfo('Token: '&CLIP(lToken))



CreateJWTToken       FUNCTION (STRING lPayload,STRING lSecret) ! Declare Procedure
stHeader      StringTheory
stPayload     StringTheory
stToEncrypt   StringTheory
stSignature   StringTheory
Crypto        Cryptonite
  CODE                                                     ! Begin processed code
  stHeader.SetValue('{{"typ":"JWT","alg":"HS256"}')
  stPayload.SetValue(CLIP(lPayload))
  stHeader.Base64Encode(1)
  stHeader.Replace('+','-')
  stHeader.Replace('/','_')
  stHeader.Replace('=','')
  stPayload.Base64Encode(1)
  stPayload.Replace('+','-')
  stPayload.Replace('/','_')
  stPayload.Replace('=','')
  stToEncrypt.SetValue(stHeader.GetValue()&'.'&stPayload.GetValue())
  Crypto.MakeHMAC(stToEncrypt,CLIP(lSecret),cs:CALG_SHA_256,0)
  stToEncrypt.Base64Encode(1)
  stToEncrypt.Replace('+','-')
  stToEncrypt.Replace('/','_')
  stToEncrypt.Replace('=','')
  RETURN stHeader.GetValue()&'.'&stPayload.GetValue()&'.'&stToEncrypt.GetValue()



A quick dirty demo, but it can be verified at https://jwt.io.


Regards
Bill

5
Web Server - Ask For Help / Re: How to be a consultant?
« on: July 21, 2021, 01:21:08 AM »
Hi Jeff,

I can help with Australian Law.

I've negotiated dozens of long term development contracts and drafted many (in conjunction with my lawyers).

I'm happy to talk, if you want.

Regards
Bill Shields







6
Web Server - Ask For Help / Re: JWT Json Web Token
« on: July 20, 2021, 06:12:54 AM »
Hi Jason,

This is me creating a JWT token for Twilio's Chat API system.


CreateTwilioToken    PROCEDURE  (STRING lAccountSID,STRING lAPIKey,STRING lAPISecret,STRING lServiceSID,STRING lPushSID,STRING lIdentity)
stHeader      StringTheory
stPayload     StringTheory 
stToEncrypt   StringTheory
stSignature   StringTheory

Crypto        Cryptonite

  CODE
  stHeader.SetValue('{{"typ":"JWT","alg":"HS256","cty":"twilio-fpa;v=1"}')

  stPayload.SetValue('{{"jti":"'&CLIP(lAPIKey)&'-'&RANDOM(100000000,999999999)&'",'&|
                       '"iss":"'&CLIP(lAPIKey)&'",'&|
                       '"sub":"'&CLIP(lAccountSID)&'",'&|
                       '"iat":'&TimestampZ()-(GETINI('Server','Timezone',0,GLO:INIFilename)*3600)&','&|
                       '"exp":'&TimestampZ()+3600-(GETINI('Server','Timezone',0,GLO:INIFilename)*3600)&','&|
                       '"grants":{{'&|
                       '"identity":"'&CLIP(lIdentity)&'",'&|
                       '"chat":{{'&|
                         '"service_sid":"'&CLIP(lServiceSID)&'",'&|
                         '"push_credential_sid":"'&CLIP(lPushSID)&'"'&|
                       '}}}')
                       
  stHeader.Base64Encode(1)
  stHeader.Replace('+','-')
  stHeader.Replace('/','_')
  stHeader.Replace('=','')
  stPayload.Base64Encode(1)
  stPayload.Replace('+','-')
  stPayload.Replace('/','_')
  stPayload.Replace('=','')
  stToEncrypt.SetValue(stHeader.GetValue()&'.'&stPayload.GetValue())
 
  Crypto.MakeHMAC(stToEncrypt,CLIP(lAPISecret),cs:CALG_SHA_256,0)
  stToEncrypt.Base64Encode(1)
  stToEncrypt.Replace('+','-')
  stToEncrypt.Replace('/','_')
  stToEncrypt.Replace('=','')
 
 
  RETURN stHeader.GetValue()&'.'&stPayload.GetValue()&'.'&stToEncrypt.GetValue()



I'm in a hurry tonight getting a build out. But, if you want the exact code, ask me on Slack.

Regards
Bill

7
Web Server - Ask For Help / Re: API Client app question
« on: July 18, 2021, 11:29:11 PM »
Hi Jeff,

I'm still running all my stuff on Windows Server 2012R2 (intentionally).

You could try AlwaysUp (https://www.coretechnologies.com/products/AlwaysUp/).

Its a program that will run your programs as a service.

I have a client who uses it and actually seems pretty good. I've not tried it on Server 2019, but they say they support it.

Might be a solution while you figure out WS2019.

Regards
Bill

8
Web Server - Ask For Help / Re: API Client app question
« on: July 18, 2021, 12:48:06 AM »
Hi Bruce,

True it does, I'd forgotten.

I'm running this stuff on servers, often as services (so I don't actually see it).

Regards
Bill


9
Web Server - Ask For Help / Re: API Client app question
« on: July 15, 2021, 01:26:47 AM »
Hi Jeff,

I'd suggest creating a separate procedure. I have a bunch of them, the simplest being:

GetWebResource(STRING URL),STRING

Pass the full URL and parameters, and it will return the result. From there you can parse or save the result.

Inside that procedure:

1. Create window
2. Add WebClient extension object
3. At window open, prime WebClient object and call Fetch
4. On PageReceived remove header and return result
5. On ErrorTrap return nothing (yes, you might want to return error messages etc, an empty result may not be sufficent - this is up to you)

Job done, now anytime you want the contents of a web page (or API) 1 call gets it for you and you don't have to worry about sync/async.

Its easily extended to add authentication and POST instead of Get for more complex APIs.

Regards
Bill


10
Web Server - Ask For Help / Re: PDF Tools 4.1 No longer sold
« on: May 25, 2021, 05:30:53 PM »
Hi Donn,

I can confirm PDFTools 4.1 is compatible with C10. I've not ported my apps to C11 (but suspect I'll be able to make it work).

I used it extensively for report conversions to PDF in my NetTalk server apps.

Regards
Bill


11
Web Server - Ask For Help / Re: How to make a "sticky" ban list.
« on: May 09, 2021, 06:21:17 PM »
Hi Donn,

This falls into two categories; access and security.

As I understand from your questions context, secwin would look after access (who can connect and what can they do when they have).

Whereas when I think of security its also about keeping people without access out.

I manage access myself. I have a table of thirdparties (APIClients). As my database stores data for many clients (Offices), the third parties are then granted permission to Clients and then further acesss to Clients data.

APIClient -->> APIClient2Office -->> SecurityArea

In my case SecurityArea refers to an arbitrary name that corresponds to a security subset (like access to CRM data, or financial data, or marketing campaign data, that sort of thing).

I'm sure SecWin does something similar (but I build this API 5 years ago, so I had to roll-my-own).

For security I use Basic authentication and require an SSL connection (Each APIClient gets their own Auth Header).

I must stress this approach is only suitable for Business-to-Business connections, with trusted servers. Customers who use this API are told so, and any detection otherwise gets their credentials revoked.

I have other APIs (like the one I mentioned that gets serious hack attempts) and those APIs are used from iOS and Android apps, and in this scenario you cannot trust SSL (at all). A completely different approach is required.

But, I'm guessing you are doing business-to-business.

Regards
Bill


12
Web Server - Ask For Help / Re: How to make a "sticky" ban list.
« on: May 03, 2021, 08:08:07 PM »
Hi Donn,

Some code, since in my above message i'm just all talk.

To check for someone on the BanList and update the ModStamp if we find them.

  Access:BanList.Open()
  BanList{PROP:SQL} = 'SELECT * FROM BanList WHERE IP='''&CLIP(GetRequestDetails(p_web,'XIP'))&''''
  NEXT(BanList)
  IF ERRORCODE() = 0
    BanList{PROP:SQL} = 'UPDATE BanList SET ModStamp='&TimestampZ()&' WHERE IP='''&CLIP(GetRequestDetails(p_web,'XIP'))&''''
    p_web.SendError(503,'Unavailable','Service unavailable')
    RETURN False
  .


In my case I have a CheckConnection() function that does numerous things including checking for Banned IPs. On a normal NT server your would place it before Process or ProcessLink etc.

This API is behind an AWS Elastic Load Balancer so to get the IP address I have to extract it from the XIP HTTP Header field. GetRequestDetails is a function of mine that does lots of things like that. You can just access FromIP from the NetTalk structures.

To put someone one the BanList.

    Access:BanList.Open()
    CLEAR(BAN:Record)
    BAN:IP = GetRequestDetails(p_web,'XIP')
    BAN:NewStamp = TimestampZ()
    BAN:ModStamp = TimestampZ()
    ADD(BanList)
    WriteToLog('BanList.LOG','IP: '&CLIP(BAN:IP)&' Date:'&FORMAT(TODAY(),@d6)&' @ '&FORMAT(CLOCK(),@t3)&' 401 Ban','')


Just all basic code. I'm not so concerned about performance as this API is sitting behind a load balancer with many EXEs doing the work, and its only handling about 100,000 calls a day.

Regards
Bill

13
Web Server - Ask For Help / Re: How to make a "sticky" ban list.
« on: May 03, 2021, 05:15:21 PM »
Hi Donn,

I have an API that is a bit target for hackers and to protect itself, other than all the usual pinned certificates to limit SLL attacks, I've taught my API to detect suspicious or dodgy behavior. When I detect it I permanently block the IP by storing it in a database table.

It could be argued (successfully) that this might be a bit slow. So you could store it in a global queue, protected by critical sections and save and load from disk appropriately.

Before I process any request I just check the incoming IP from my list of bad actors and return a 503 is I don't like them.

Its worth mentioning, that all servers will get loads of traffic with people snooping around, testing for vulnerabilities, these do not concern me. I just ignore them.

For some of my systems that aren't world wide, I will use a geo-block at my router level (since it knows how to do it for me), thus removing a great deal of the dodgy traffic from dodgy countries.

I do have 1 API that gets malice attacks, where there is a real hacker (and very capable ones) at the other end. It is only this API that I block bad IPs. I have honey-pot style end-points or parameters for end-points and when they try and use them, permanent ban.

Some of my hackers have been white hat guys, so i've had the opportunity to talk to them about their techniques and they have shown me the issues i'm dealing with.

Its effectiveness is also, limited, most hackers will access your system via proxies or other peoples compromised systems. So they can just get other IP addresses. My rationale here, is to hack my API they need some level of continuity as they probe my API for weaknesses and the IP Ban, breaks their "stride" and makes the process more difficult as more and more of their IPs get Banned. Basically it just slows them down.

In short, if its just muppets looking for systems with default passwords, or generic word press, mysql, etc vulnerabilities I wouldn't bother. But, if you have very valuable data that other people will risk jail to find, then yes, block if you can.

Regards
Bill


14
Web Server - Ask For Help / Re: Multiple instances of an API-server?
« on: April 12, 2021, 01:13:53 AM »
Hi,

I do this via either Elastic Load Balancer (when hosted on AWS) or in hardware on my fortinet routers.

Most enterprise routers support load balancing.

You just run numerous instances of your API on different ports or internal IPs, on the same or different servers. Then setup your load balancer, it appears as a single end point for the outside world and then routes to numerous actual worker servers.

If you share your infrastructure I can be more specific.

Regards
Bill

15
Web Server - Ask For Help / Re: Generate GUID in SQL
« on: October 18, 2020, 03:01:27 PM »
MySQL has a function called UUID() that will do this for you. Other SQLs probably have similar functions.

You can even add it to an insert trigger and it will prime itself for you. But from memory, Clarion PROP:ServerAutoInc can't handle this (or at least I haven't bothered to find out how to get it to work).

Pages: [1] 2 3 ... 25