How to communicate over sockets in Clozure Common Lisp? - sockets

In one CCL REPL I enter:
(WITH-OPEN-SOCKET (socket :LOCAL-PORT 6667
:LOCAL-HOST "localhost"
:CONNECT :PASSIVE
:REUSE-ADDRESS t)
(let ((stream (ACCEPT-CONNECTION socket :wait t)))
(format stream "hello from server.~%")))
It waits for a connection.
In another CCL process I enter:
(WITH-OPEN-SOCKET (socket-stream :REMOTE-PORT 6667
:REMOTE-HOST "localhost"
:CONNECT :ACTIVE
:REUSE-ADDRESS t)
(format t (READ-LINE socket-stream)))
At this point this process goes into waiting. It neither reads from the server, nor exits.
However, the moment the client connects to the server, the server exits with NIL. So clearly a connection is at least established, but the string "Hello from server." never gets communicated.
I am sure this is something basic I am overlooking. How do I send messages across? Is READ-LINE not the right way to read from a stream? Am I writing from the server incorrectly? How would I establish a bi-directional simple string based communication?

You know that output can be buffered?
That's one typical problem. see FINISH-OUTPUT and FORCE-OUTPUT.
If you write to a buffered stream, you have to make sure that the buffered output is actually fully delivered.
? (WITH-OPEN-SOCKET (socket-stream :REMOTE-PORT 6667
:REMOTE-HOST "localhost"
:CONNECT :ACTIVE
:REUSE-ADDRESS t)
(format t (READ-LINE socket-stream)))
hello from server.
NIL
---
? (WITH-OPEN-SOCKET (socket :LOCAL-PORT 6667
:LOCAL-HOST "localhost"
:CONNECT :PASSIVE
:REUSE-ADDRESS t)
(let ((stream (ACCEPT-CONNECTION socket :wait t)))
(format stream "hello from server.~%")
(finish-output stream)
stream))
#<BASIC-TCP-STREAM ISO-8859-1 (SOCKET/21) #x302000E3FD9D>

Related

How to set CORs using Lacinia Pedestal?

I'm setting up a lacinia-pedestal graphql server using Clojure, and attempting to access it with client-side javascript code using apollo. However, I'm unable to access the /graphql endpoint on localhost because I'm attempting to access it from a localhost origin (localhost:3000) that is not allowed by CORs. How do I set CORs using lacinia-pedestal?
Here is the server-side code (set up using the lacinia tutorial https://lacinia.readthedocs.io/en/latest/tutorial/component.html)
(ns project.server
(:require [com.stuartsierra.component :as component]
[com.walmartlabs.lacinia.pedestal :as lp]
[io.pedestal.http :as http]))
(defrecord Server [schema-provider server]
component/Lifecycle
(start [this]
(assoc this :server (-> schema-provider
:schema
(lp/service-map {:graphiql true})
http/create-server
http/start)))
(stop [this]
(http/stop server)
(assoc this :server nil)))
(defn new-server
[]
{:server (-> {}
map->Server
(component/using [:schema-provider]))})
Client-side code is super simple (using Apollo):
const client = new ApolloClient({
uri: "http://localhost:8888/graphql"
});
Update: I managed to solve it by merging my lacinia pedestal service map with a standard pedestal service map.
(start [this]
(assoc this :server (-> schema-provider
:schema
(lp/service-map {:graphiql true})
(merge {::http/allowed-origins (constantly true)})
http/create-server
http/start)))

timeout error with usocket on common lisp

I’m having trouble with cl-smtp:send-email which seems to stem from a timeout error when calling usocket:socket-connect.
Here is what I am trying to do:
(cl-smtp:send-email "outgoing.mit.edu" "m_klein#mit.edu"
(list "m_klein#mit.edu") "s1" "m1”)
This seems to be the call where the failure occurs (according to the backtrace):
(usocket:socket-connect "outgoing.mit.edu" 25
:protocol :stream
:element-type '(unsigned-byte 8)
:timeout nil
:deadline nil
:nodelay nil
:local-host nil
:local-port nil)
Here is the error:
Error: Error #<USOCKET:TIMEOUT-ERROR #x302001E5FDED>
While executing: USOCKET::RAISE-ERROR-FROM-ID, in process Listener(475).
The odd thing is that the same function call has worked on other machines, but not on my current mac laptop or the cloud-based mac I’ve also been using.
I am running Clozure Common Lisp 1.11.1 on a MacBook Pro on OS 10.13.3
Here are snapshots of the backtrace FYI: https://imgur.com/a/e2xcf
Any ideas? Any help would be greatly appreciated.
Since you are using an external server, first you need to check, correctness of the address (connect using telnet), port and maybe you need an authentication.
Since you are using cl-smtp, first I recommend you to test how it works, for that the easy way of testing smptp is using mailcatcher inside a docker container:
docker run -d -p 1080:1080 -p 1025:1025 --name mailcatcher schickling/mailcatcher
docker ps | grep mailcatcher
6fb056fceb6b schickling/mailcatcher "mailcatcher -f --ip…" 9 months ago Up 18 minutes 0.0.0.0:1025->1025/tcp, 0.0.0.0:1080->1080/tcp mailcatcher
Then you can access to the ourtgoing mail in a web browser localhost:1080, and send mail to localhost:1025
For testing the SMTP, server I recommend to use telnet:
telnet
telnet> o localhost 1025
Trying ::1...
Connected to localhost.
Escape character is '^]'.
220 EventMachine SMTP Server
EHLO localhost
250-Ok EventMachine SMTP Server
250-NO-SOLICITING
250 SIZE 20000000
there is a great article on that here
When you are sure that, you get the requirements try with lisp:
CL-USER> (cl-smtp:send-email "127.0.0.1" "antonio.querol#example.com" "pedro.lopez#example.com" "Say Hello" "Hello World"
:port 1025)
("Ok")

Configuring gnus with gmail imap

I am trying to configure gnus to work with my gmail account. My .gnus file looks like this:
(setq gnus-select-method '(nntp "news.gwene.org"))
(setq user-full-name "George P. Burdell")
(setq user-mail-address "probablyReal#gmail.com")
(setq smtpmail-auth-credentials "~/.authinfo.epg")
(add-to-list 'gnus-secondary-select-methods
'(nnimap "gmail"
(nnimap-address "imap.gmail.com")
(nnimap-server-port 993)
(nnimap-stream ssl)
(nnimap-authinfo-file "~/.authinfo.epg")
)
)
(setq smtpmail-stream-type 'ssl
smtpmail-smtp-server "smtp.gmail.com"
smtpmail-smtp-service 465)
and my .authinfo.epg file looks like this:
machine imap.gmail.com login probablyReal#gmail.com password secret port 993
machine smtp.gmail.com login probablyReal#gmail.com password secret port 465
and the error that it throws is:
Generating the cache active file...done
Opening nnfolder server on archive...done
Opening nnimap server on gmail...
Opening connection to imap.gmail.com via tls...
Opening TLS connection to `imap.gmail.com'...
Opening TLS connection with `gnutls-cli --insecure -p 993 imap.gmail.com'...failed
Opening TLS connection with `gnutls-cli --insecure -p 993 imap.gmail.com --protocols ssl3'...failed
Opening TLS connection with `openssl s_client -connect imap.gmail.com:993 -no_ssl2 -ign_eof'...failed
Opening TLS connection to `imap.gmail.com'...failed
Unable to open server nnimap+gmail due to: Buffer *nnimap imap.gmail.com 993 *nntpd** has no process
Opening nnimap server on gmail...failed:
No new newsgroups
Checking new news...
Reading active file from gmail via nnimap...
Opening nnimap server on gmail...
Server nnimap+gmail previously determined to be down; not retrying
Opening nnimap server on gmail...failed:
Reading active file via nndraft...done
Checking new news...done
Warning: Opening nnimap server on gmail...failed: ; Server nnimap+gmail previously determined to be down; not retrying; Opening nnimap server on gmail...failed: ; Unable to open server nnimap+gmail due to: Buffer *nnimap imap.gmail.com 993 *nntpd** has no process
(sorry for wall of text)
finally, when I evaluate this:
(gnutls-available-p)
it simply prints:
nil
I'm running emacs for windows 8, I'm not using cygwin, and I really can't figure out what the problem is, even after seraching for hours.
edit: I've tried both of these (as well as combinations from both) and get the same errors:
http://blog.binchen.org/posts/notes-on-using-gnus.html
http://www.emacswiki.org/emacs/GnusGmail
My guess would be that Emacs on Windows doesn't come with the required libraries, hence (gnutls-available-p) returns nil for you. You'll have to install gnutls somewhere so that your Emacs will be able to find it, cf. the GnuTLS homepage. You probably have to put the downloaded Windows library into the directory where Emacs is looking for it's libraries.

Sending emails with emacs24 via smtp with gnutls and extra arguments

I have a rather weird problem with using sending out emails from emacs24 with my posteo email account, but everything seems to work just fine with gmail and gmx. This is the relevant part of my current .emacs configuration (it feels like I permuted it a million times with always the same results):
(require 'smtpmail)
(require 'starttls)
(setq message-send-mail-function 'smtpmail-send-it)
(setq tls-program '("gnutls-cli --priority NORMAL:%COMPAT -p %p %h"))
(setq starttls-gnutls-program "gnutls-cli --priority NORMAL:%COMPAT")
(setq starttls-use-gnutls t)
(setq smtpmail-stream-type 'starttls)
(setq smtpmail-smtp-server "posteo.de")
(setq smtpmail-debug-info t)
(setq smtpmail-debug-verb t)
(setq smtpmail-smtp-service 587) ;;587(starttls) or 465(tls/ssl) or ?
(setq starttls-extra-arguments '("--priority NORMAL:%COMPAT"))
The output in my message buffer is:
Sending via mail...
235 2.7.0 Authentication successful
gnutls.c: [0] (Emacs) fatal error: A TLS fatal alert has been received.
gnutls.c: [0] (Emacs) Received alert: Bad record MAC
smtpmail-send-command: Process smtpmail not running
and in my trace of SMTP to posteo.de buffer:
220 mail.posteo.de ESMTP Postfix
250-mail.posteo.de
250-PIPELINING
250-SIZE 76800000
250-VRFY
250-ETRN
250-STARTTLS
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
220 2.0.0 Ready to start TLS
250-mail.posteo.de
250-PIPELINING
250-SIZE 76800000
250-VRFY
250-ETRN
250-AUTH PLAIN LOGIN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
AUTH PLAIN <omitted>
235 2.7.0 Authentication successful
Process smtpmail connection broken by remote peer
MAIL FROM:<c.bourjau#posteo.de> SIZE=281
QUIT
The problem seems to be a certificate which appears to have wrong "paddings" (I am not really sure what this is) http://gnutls.org/manual/html_node/On-Record-Padding.html. Another way to produce a similar error on the command line with this server is to do:
$ gnutls-cli --starttls -p 587 posteo.de
Resolving 'posteo.de'...
Connecting to '89.146.220.134:587'...
- Simple Client Mode:
220 mail.posteo.de ESMTP Postfix
*** Starting TLS handshake
*** Fatal error: An unexpected TLS packet was received.
*** Handshake has failed
This error is supposedly fixed if one adds the --priority NORMAL:%COMPAT to the gnutls argument which I tried to no avail (see .emacs).
So the question is: How does on treat certifcates throwing these kind of errors in emacs?
Thanks a lot in advance!
This post gave me the crucial hint: How to ask gnutls to use client certificate in emacs 24
emacs24 seems to ignore the starttls-gnutls-program variable if gnutls-available-p is not nil, which has to be force by overwriting the latter function.
My working configuration is now the following:
(require 'smtpmail)
(require 'starttls)
(setq message-send-mail-function 'smtpmail-send-it)
(defun gnutls-available-p ()
"Function redefined in order not to use built-in GnuTLS support"
nil)
(setq starttls-gnutls-program "gnutls-cli")
(setq starttls-use-gnutls t)
(setq smtpmail-stream-type 'starttls)
(setq smtpmail-smtp-server "posteo.de")
(setq smtpmail-smtp-service 587) ;;587(starttls) or 465(tls/ssl)
(setq starttls-extra-arguments '("--priority" "NORMAL:%COMPAT"))

smtpmail error "An unexpected TLS packet was received"

I write emails in emacs via mu4e. If I specify starttls instead of ssl in the following code, smtpmail can send the messages:
;; sending mail (see Appendix B.3.2 of the mu4e manual)
(setq send-mail-function 'smtpmail-send-it
messsage-send-mail-function 'smtpmail-send-it; use smtpmail for sending mails
smtpmail-stream-type 'ssl; starttls works here, why not ssl?
smtpmail-default-smtp-server "mail.uni.edu"; default smtp server
smtpmail-smtp-server "mail.uni.edu"; host name of the SMTP server
smtpmail-smtp-service "smtp"); controls the port on the server to contact
However, for ssl, I obtain (output of *Messages*):
Sending via mail...
gnutls.c: [0] (Emacs) fatal error: An unexpected TLS packet was received.
gnutls.el: (err=[-15] An unexpected TLS packet was received.) boot: (:priority NORMAL :hostname mail.ethz.ch :loglevel 0 :min-prime-bits 256 :trustfiles (/etc/ssl/certs/ca-certificates.crt) :crlfiles nil :keylist nil :verify-flags nil :verify-error nil :verify-hostname-error nil :callbacks nil)
gnutls-negotiate: GnuTLS error: #<process smtpmail>, -15
gnutls.c: [0] (Emacs) fatal error: An unexpected TLS packet was received. [100 times]
What's wrong?
Replace "smtp" by 465 and it works.